在计算机中,按照颜色和灰度的多少可以将图像分为二值图像、灰度图像、索引图像和真彩色RGB图像四种基本类型。目前,大多数图像处理软件都支持这四种类型的图像。
二值图像:
一幅二值图像的二维矩阵仅由0、1两个值构成,“0”代表黑色,“1”代白色。由于每一像素(矩阵中每一元素)取值仅有0、1两种可能,所以计算机中二值图像的数据类型通常为1个二进制位。二值图像通常用于文字、线条图的扫描识别(OCR)和掩膜图像的存储。
灰度图像:
灰度图像矩阵元素的取值范围通常为[0,255]。因此其数据类型一般为8位无符号整数的(int8),这就是人们经常提到的256灰度图像。“0”表示纯黑色,“255”表示纯白色,中间的数字从小到大表示由黑到白的过渡色。在某些软件中,灰度图像也可以用双精度数据类型(double)表示,像素的值域为[0,1],0代表黑色,1代表白色,0到1之间的小数表示不同的灰度等级。二值图像可以看成是灰度图像的一个特例。
索引图像:
彩色图像:
通道,位的理解
通俗点可以把一种颜色理解为一个通道,如RGB模式就是有R(红)、G(绿)、B(蓝)三个通道,灰度模式的图像只有一个灰度通道。位,就是每种色由浅到深所分的阶数。如8位就是每种颜色分为256阶(2的8次方),16位就是每种颜色分为2的16次方阶。(可以这样理解,表述并不完全准确)
上面说的通道是相关图像模式的,一般显示用的图片都是RGB模式,8位通道,印刷用的是CMYK模式。16位通道图极少用到,除非特殊要求。
通道还包括Alpha通道,颜色通道,专色通道等。
通道还有其它作用,主要有:
⑴ 表示选择区域,也就是白色代表的部分。利用通道,你可以建立头发丝这样的精确选区。
⑵ 表示墨水强度。利用Info面板可以体会到这一点,不同的通道都可以用256级灰度来表示不同的亮度。在Red通道里的一个纯红色的点,在黑色的通道上显示就是纯黑色,即亮度为0。
⑶ 表示不透明度。其实这是我们平时最乐于使用的一个**能。或许你曾经看到过一座高山渐隐融入到水中的图片?是不是也曾羡慕不已?那么,就记住通道吧,你爱它,它就会帮你。
⑷ 表示颜色信息。不妨实验一下,预览Red通道,无论你的鼠标怎样移动,Info面板上都仅有R值,其余的都为0。
IplImage定义:
CV_IMAGE_ELEM读取某点的像素
可以使用opencv定义的宏来提取象素值
假设灰度图像image,存取其i行j列的象素可以这样:CV_IMAGE_ELEM(image, uchar,y, x)
如果是彩色图像就是
CV_IMAGE_ELEM(image, uchar,y, 3*x)
CV_IMAGE_ELEM(image, uchar,y, 3*x+1)
CV_IMAGE_ELEM(image, uchar,y, 3*x+2)
CV_IMAGE_ELEM是一个宏,
#define CV_IMAGE_ELEM( image, elemtype, row, col ) \
(((elemtype*)((image)->imageData + (image)->widthStep*(row)))[(col)])
#define CV_MAT_ELEM( mat, elemtype, row, col ) \
(*(elemtype*)CV_MAT_ELEM_PTR_FAST( mat, row, col, sizeof(elemtype)))
呵呵,我一直把它当一个函数用,其实本质也没有什么区别的
但要想正确的得到图像的坐标为(x,y)点的像素值,是应该这样写CV_IMAGE_ELEM(Image, uchar, y, x)
要注意像素点的坐标xy和行列值的顺序是相反的(可以仔细思考为什么)
我刚开始一直写成CV_IMAGE_ELEM(Image, uchar, x, y),结果有时候就造成了访问image越界,从而报错,花了好长时间才捣鼓出来,
不过将IMAGE的数据按照原来的样子复制到mat中可以这么写:
CV_IMAGE_ELEM(pImage, uchar, i, j) = CV_MAT_ELEM(*mat, uchar, i, j)
不用改变顺序
总之,当应用这个宏是如果老报错,就试试换个顺序,或者检查访问的地址是否越界