{"id":745,"date":"2013-01-15T12:52:27","date_gmt":"2013-01-15T17:52:27","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=745"},"modified":"2019-11-01T09:09:15","modified_gmt":"2019-11-01T13:09:15","slug":"data-types","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2013\/01\/15\/data-types\/","title":{"rendered":"Digital Image Processing Using MATLAB: Data Types"},"content":{"rendered":"<div class=\"content\"><p><i>Today's post is part of an <a href=\"https:\/\/blogs.mathworks.com\/steve\/category\/dipum-tutorials\/\">ongoing tutorial series on digital image processing using MATLAB<\/a>. I'm covering topics in roughly the order used in the book <a href=\"http:\/\/imageprocessingplace.com\/DIPUM-2E\/dipum2e_main_page.htm\">Digital Image Processing Using MATLAB<\/a>.<\/i><\/p><p>When working with images in MATLAB, it is important to understand how different numeric data types can come into play.<\/p><p>The most common numeric data type in MATLAB is <tt>double<\/tt>, which stands for <i>double-precision floating point<\/i>. It's the representation of numbers that you get by default when you type numbers into MATLAB.<\/p><pre class=\"codeinput\">a = [0.1 0.125 1.3]\r\n<\/pre><pre class=\"codeoutput\">\r\na =\r\n\r\n    0.1000    0.1250    1.3000\r\n\r\n<\/pre><pre class=\"codeinput\">class(a)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\ndouble\r\n\r\n<\/pre><p>Double-precision floating-point numbers are intended to approximate the set of real numbers. To a reasonable degree, one can do arithmetic computations on these numbers using MATLAB (and the computational hardware on your CPU or GPU) and get the same results as \"true arithmetic\" (or \"God's math,\" as I've heard Cleve say) on the real numbers.<\/p><p>Working with floating-point numbers is very useful for mathematical image processing algorithms (such as filtering, Fourier transforms, deblurring, color computations, and many others).<\/p><p>Prior to 1997, the <tt>double<\/tt> was the only kind of data type in MATLAB. Image processing customers complained about this because of the memory required for these kinds of numbers. A double-precision floating-point number requires 64 bits, whereas many people working with image data were used to using only 8 bits (or even just 1 bit in the case of binary images) to store each pixel value.<\/p><p>So with MATLAB 5 and Image Processing Toolbox 2 in 1997, we introduced support for a new data type, <tt>uint8<\/tt>, which is an abbreviation for <i>unsigned 8-bit integer<\/i>. This data requires just 8 bits to represent a number, but the representable set of numbers is limited to the integers from 0 to 255.<\/p><p>You can make one in MATLAB by calling the <tt>uint8<\/tt> function.<\/p><pre class=\"codeinput\">b = uint8(5)\r\n<\/pre><pre class=\"codeoutput\">\r\nb =\r\n\r\n    5\r\n\r\n<\/pre><pre class=\"codeinput\">class(b)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\nuint8\r\n\r\n<\/pre><p>Also, you often see <tt>uint8<\/tt> numbers when you call the <tt>imread<\/tt> to read an image from a file. That's because image file formats often use 8 bits (prior to compression) to store each pixel value.<\/p><pre class=\"codeinput\">rgb = imread(<span class=\"string\">'peppers.png'<\/span>);\r\nrgb(1:3,1:4,1)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n   62   63   63   65\r\n   63   61   59   64\r\n   65   63   63   66\r\n\r\n<\/pre><pre class=\"codeinput\">class(rgb)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\nuint8\r\n\r\n<\/pre><p>Almost immediately after MATLAB 5 and Image Processing Toolbox 2, we started hearing from customers who had scientific data stored using 16 bits for value, so 8 bits wasn't enough and 64 bits (for <tt>double<\/tt>) still seemed wasteful. So Image Processing Toolbox 2.2 in 1999 added support for <tt>uint16<\/tt> numbers (unsigned 16-bit integers).<\/p><p>But still that wasn't enough. The medical imaging community, it seemed, needed <b>signed<\/b> 16-bit numbers. And, said many, what about single-precision floating-point?<\/p><p>For Image Processing Toolbox 3 in 2001, we stopped adding data type support piecemeal and instead added support for all the data types in MATLAB at the time. Here is a summary of the entire set:<\/p><div><ul><li><tt>double<\/tt> - double-precision, floating-point numbers in the approximate range $\\pm 10^{308}$ (8 bytes per number)<\/li><li><tt>single<\/tt> - single-precision, floating-point numbers with values in the approximate range $\\pm 10^{38}$ (4 bytes per number)<\/li><li><tt>uint8<\/tt> - unsigned 8-bit integers in the range [0,255] (1 byte per number)<\/li><li><tt>uint16<\/tt> - unsigned 16-bit integers in the range [0,65535] (2 bytes per number)<\/li><li><tt>uint32<\/tt> - unsigned 32-bit integers in the range [0,4294967295] (4 bytes per number)<\/li><li><tt>int8<\/tt> - signed 8-bit integer in the range [-128,127] (1 byte per number)<\/li><li><tt>int16<\/tt> - signed 16-bit integer in the range [-32768,32767] (2 bytes per number)<\/li><li><tt>int32<\/tt> - signed 32-bit integer in the range [-2147483648,2147483647] (4 bytes per number)<\/li><\/ul><\/div><p>Support for the <tt>logical<\/tt> data type (the only values are 0 and 1, 1 byte per number) was added a few years later.<\/p><p>Two other data types have appeared since then, <tt>uint64<\/tt> and <tt>int64<\/tt>. Relatively little effort has been made to support these data types for image processing, for two reasons:<\/p><div><ul><li>We don't get any customer requests for it<\/li><li>There are hard-to-answer behavior questions caused by the fact that there are <tt>uint64<\/tt> and <tt>int64<\/tt> numbers that can't be exactly represented as <tt>double<\/tt>, and some Image Processing Toolbox functions have an implicit assumption that one can convert an integer number to a double-precision floating-point number and back again without losing information in the process. But, as it turns out, there are plenty of large unsigned 64-bit numbers that can't be represented exactly in double-precision floating-point:<\/li><\/ul><\/div><pre class=\"codeinput\">c = uint64(184467440737095516)\r\n<\/pre><pre class=\"codeoutput\">\r\nc =\r\n\r\n   184467440737095516\r\n\r\n<\/pre><pre class=\"codeinput\">d = double(c)\r\n<\/pre><pre class=\"codeoutput\">\r\nd =\r\n\r\n   1.8447e+17\r\n\r\n<\/pre><pre class=\"codeinput\">e = uint64(d)\r\n<\/pre><pre class=\"codeoutput\">\r\ne =\r\n\r\n   184467440737095520\r\n\r\n<\/pre><pre class=\"codeinput\">e - c\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n                    4\r\n\r\n<\/pre><p>When I pursue this topic further next time, I'll talk more about data type conversions: the basic ones in MATLAB, plus the Image Processing Toolbox ones that handle additional details of data scaling.<\/p><p>For more information, see Section 2.5 of <a href=\"http:\/\/imageprocessingplace.com\/DIPUM-2E\/dipum2e_main_page.htm\"> <i>Digital Image Processing Using MATLAB<\/i><\/a>.<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2011\/dipum-cover.png\" alt=\"\"> <\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_3a960eb541034f2c838285a05d0618bf() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='3a960eb541034f2c838285a05d0618bf ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 3a960eb541034f2c838285a05d0618bf';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2013 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_3a960eb541034f2c838285a05d0618bf()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2012b<br><\/p><p class=\"footer\"><br>\r\n      Published with MATLAB&reg; R2012b<br><\/p><\/div><!--\r\n3a960eb541034f2c838285a05d0618bf ##### SOURCE BEGIN #####\r\n%% Images and data types\r\n% _Today's post is part of an\r\n% <https:\/\/blogs.mathworks.com\/steve\/category\/dipum-tutorials\/ ongoing\r\n% tutorial series on digital image processing using MATLAB>. I'm covering\r\n% topics in roughly the order used in the book\r\n% <http:\/\/imageprocessingplace.com\/DIPUM-2E\/dipum2e_main_page.htm Digital\r\n% Image Processing Using MATLAB>._\r\n%\r\n% When working with images in MATLAB, it is important to understand how\r\n% different numeric data types can come into play.\r\n%\r\n% The most common numeric data type in MATLAB is |double|, which stands for\r\n% _double-precision floating point_. It's the representation of numbers\r\n% that you get by default when you type numbers into MATLAB.\r\n\r\na = [0.1 0.125 1.3]\r\n\r\n%%\r\nclass(a)\r\n\r\n%%\r\n% Double-precision floating-point numbers are intended to approximate the\r\n% set of real numbers. To a reasonable degree, one can do arithmetic\r\n% computations on these numbers using MATLAB (and the computational\r\n% hardward on your CPU or GPU) and get the same results as \"true\r\n% arithmetic\" (or \"God's math,\" as I've heard Cleve say) on the real\r\n% numbers.\r\n%\r\n% Working with floating-point numbers is very useful for mathematical image\r\n% processing algorithms (such as filtering, Fourier transforms, deblurring,\r\n% color computations, and many others).\r\n%\r\n% Prior to 1997, the |double| was the only kind of data type in MATLAB.\r\n% Image processing customers complained about this because of the memory\r\n% required for these kinds of numbers. A double-precision floating-point\r\n% number requires 64 bits, whereas many people working with image data were\r\n% used to using only 8 bits (or even just 1 bit in the case of binary\r\n% images) to store each pixel value.\r\n%\r\n% So with MATLAB 5 and Image Processing Toolbox 2 in 1997, we introduced\r\n% support for a new data type, |uint8|, which is an abbreviation for\r\n% _unsigned 8-bit integer_. This data requires just 8 bits to represent a\r\n% number, but the representable set of numbers is limited to the integers\r\n% from 0 to 255.\r\n%\r\n% You can make one in MATLAB by calling the |uint8| function.\r\n\r\nb = uint8(5)\r\n\r\n%%\r\nclass(b)\r\n\r\n%%\r\n% Also, you often see |uint8| numbers when you call the |imread| to read an\r\n% image from a file. That's because image file formats often use 8 bits\r\n% (prior to compression) to store each pixel value.\r\n\r\nrgb = imread('peppers.png');\r\nrgb(1:3,1:4,1)\r\n\r\n%%\r\nclass(rgb)\r\n\r\n%%\r\n% Almost immediately after MATLAB 5 and Image Processing Toolbox 2, we\r\n% started hearing from customers who had scientific data stored using 16\r\n% bits for value, so 8 bits wasn't enough and 64 bits (for |double|) still\r\n% seemed wasteful. So Image Processing Toolbox 2.2 in 1999 added support\r\n% for |uint16| numbers (unsigned 16-bit integers).\r\n%\r\n% But still that wasn't enough. The medical imaging community, it seemed,\r\n% needed *signed* 16-bit numbers. And, said many, what about\r\n% single-precision floating-point?\r\n%\r\n% For Image Processing Toolbox 3 in 2001, we stopped adding data type\r\n% support piecemeal and instead added support for all the data types\r\n% in MATLAB at the time. Here is a summary of the entire set:\r\n%\r\n% * |double| - double-precision, floating-point numbers in the approximate\r\n% range $\\pm 10^{308}$ (8 bytes per number)\r\n% * |single| - single-precision, floating-point numbers with values in the\r\n% approximate range $\\pm 10^{38}$ (4 bytes per number)\r\n% * |uint8| - unsigned 8-bit integers in the range [0,255] (1 byte per\r\n% number)\r\n% * |uint16| - unsigned 16-bit integers in the range [0,65535] (2 bytes per\r\n% number)\r\n% * |uint32| - unsigned 32-bit integers in the range [0,4294967295] (4\r\n% bytes per number)\r\n% * |int8| - signed 8-bit integer in the range [-128,127] (1 byte per\r\n% number)\r\n% * |int16| - signed 16-bit integer in the range [-32768,32767] (2 bytes\r\n% per number)\r\n% * |int32| - signed 32-bit integer in the range [-2147483648,2147483647]\r\n% (4 bytes per number)\r\n%\r\n% Support for the |logical| data type (the only values are 0 and 1, 1 byte\r\n% per number) was added a few years later.\r\n%\r\n% Two other data types have appeared since then, |uint64| and |int64|.\r\n% Relatively little effort has been made to support these data types for\r\n% image processing, for two reasons:\r\n%\r\n% * We don't get any customer requests for it\r\n% * There are hard-to-answer behavior questions caused by the fact that\r\n% there are |uint64| and |int64| numbers that can't be exactly represented\r\n% as |double|, and some Image Processing Toolbox functions have an implicit\r\n% assumption that one can convert an integer number to a double-precision\r\n% floating-point number and back again without losing information in the\r\n% process. But, as it turns out, there are plenty of large unsigned 64-bit\r\n% numbers that can't be represented exactly in double-precision\r\n% floating-point:\r\n\r\nc = uint64(184467440737095516)\r\n\r\n%%\r\n\r\nd = double(c)\r\n\r\n%%\r\n\r\ne = uint64(d)\r\n\r\n%%\r\n\r\ne - c\r\n\r\n%%\r\n% When I pursue this topic further next time, I'll talk more about data\r\n% type conversions: the basic ones in MATLAB, plus the Image Processing\r\n% Toolbox ones that handle additional details of data scaling.\r\n\r\n%%\r\n% For more information, see Section 2.5 of\r\n% <http:\/\/imageprocessingplace.com\/DIPUM-2E\/dipum2e_main_page.htm\r\n%  _Digital Image Processing Using MATLAB_>. \r\n%\r\n% <<https:\/\/blogs.mathworks.com\/images\/steve\/2011\/dipum-cover.png>>\r\n##### SOURCE END ##### 3a960eb541034f2c838285a05d0618bf\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2011\/dipum-cover.png\" onError=\"this.style.display ='none';\" \/><\/div><p>Today's post is part of an ongoing tutorial series on digital image processing using MATLAB. I'm covering topics in roughly the order used in the book Digital Image Processing Using MATLAB.When... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2013\/01\/15\/data-types\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[21],"tags":[917,402,76,965,967,971,963,330,559,961,557,969,555],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/745"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/comments?post=745"}],"version-history":[{"count":9,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/745\/revisions"}],"predecessor-version":[{"id":3809,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/745\/revisions\/3809"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=745"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=745"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=745"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}