先贴一下代码:
- <PRE></PRE>
- <P><SPAN style="FONT-SIZE: 18px; FONT-FAMILY: Microsoft YaHei">起初,没有红色的行,显示结果如下(左边是原图,右边是处理后的图):</SPAN></P>
- <SPAN style="FONT-SIZE: 18px; FONT-FAMILY: 微软雅黑"></SPAN>
- <P><IMG alt="" src="http://hi.csdn.net/attachment/201203/13/0_1331647160Iba4.gif"></P>
- <P><SPAN style="FONT-SIZE: 18px; FONT-FAMILY: Microsoft YaHei">加上红色的行后,显示如下:</SPAN></P>
- <P><SPAN style="FONT-SIZE: 18px; FONT-FAMILY: Microsoft YaHei"><IMG alt="" src="http://hi.csdn.net/attachment/201203/13/0_13316472725Dwj.gif"></SPAN></P>
- <SPAN style="FONT-SIZE: 18px; FONT-FAMILY: Microsoft YaHei"></SPAN>
- <PRE></PRE>
起初,没有红色的行,显示结果如下(左边是原图,右边是处理后的图):
加上红色的行后,显示如下:
灰度反转代码比较简单,起初也弄不清问题出在哪里,想能出问题的地方也就zeros 和imshow函数,查了一下这两个函数,果然找到问题。
先看zeros函数:
zeros函数族中有个函数为: zeros(m, n ,... classname) ,其中classname可以取“double”, "uint8", "int8"等等(默认取double). 正因为zeros默认类型是double才导致我一开始的错误。(其实,matlab中的图像经过运算后类型都会转化为double,这样可以防止溢出,并保证精度)
在一开始,矩阵J的数据类型为double, 在进行了下面的反转运算后,J中的值的取值范围为[0 255] ,下面我们再看一下imshow函数的一段说明:
- <SPAN style="FONT-SIZE: 16px">% If your grayscale image is single or double, the default display range is
- % [0 1]. If your image\'s data range is much larger or smaller than the default
- % display range, you may need to experiment with setting the display range to
- % see features in the image that would not be visible using the default
- % display range. For all grayscale images having integer types, the default
- % display range is [intmin(class(I)) intmax(class(I))].
- </SPAN>
即,如果imshow的参数类型为double ,那么参数的取值范围只有在[0 1]才会正常显示。当值大于1时,都显示白色。这与matlab的传统是一致的, 对于灰度图像,uint8表示范围是[0 255] ,double表示范围是[0 1]
正因为imshow的限制,我才在一开始没有得出正确的结果。
但是,imshow函数的一个重载形式可以帮助我们解决这个问题, imshow(I, [low high]) (具体可以查看help) ,如果我们使用imshow(I, []) ,那么imshow将使用范围[min(I(:)), max(I(:))] ,即图像I中的最小值显示为黑色,最大值显示为白色(属于图像灰度拉伸的方法)
解决:
1.如上面程序做法,显示的将J转化为uint8类型
2.如上面所述, 使用J =zeros(m,n,\'uint8\')
3. 使用imshow(J,[])
4. imshow(J/256)
但是上面各种方法的效果还是有区别的,我实验了最后两个方法的效果,发现方法3的对比要强烈一些 ,如下图:
默认情况下, matlab将图像的数据类型存储为double型。当然,matlab为了节省空间,支持uint8, uint16等。但是在运算时最好转化为double型,这样可以保证计算的精度,也会防止溢出。当然,如果要显示图像,还是要调整为图像的标准数据格式。
im2uint8 和 uint8 都是将图像数据转化为uint8 ,前者要求被转化的数据必须是符合图像数据标准(如:double [0 1]) ,而uint8则不必,它会自动截断数据
im2double 和double 。double就是将一个数据的类型转化为double ,但是数值不变;im2double将输入的uint8或uint16归一化到[0 1]区间 ,如果输入是double,则不进行归一化。