一直在看opencv,但都是断断续续,不成体系,知识点过于凌乱,今天第一次做笔记,为了自己更好的理解,也为了有和我一样兴趣的人参考。正文如下:
这篇笔记主要记录一下图像元素的访问:
单通道字节图像的访问
1.用cvGet2D()和cvSet2D():
cvGet2D()函数的原型:CvScalar cvGet2D( const CvArr* arr, int idx0, int idx1 ),返回的是一个CvScalar类型的容器,idx0和idx1分别表示的是该点到图像(0,0)点的垂直距离和水平距离,和我们一般理解的相反。
cvSet2D也类似,只不过加了一个要设置的cvScalar类型的参数
例如:
cvScalar test;
IplImage* image = cvCreateImage(cvSize(200,200),IPL_DEPTH_8U,1);//创建一个单通道无符号整形字节图像
test = cvGet2D(image,x,y);//返回的数据赋值给cvScalar类型的test
printf("result:%f\n",test.val[0]);//列印出单通道(x,y)的值
cvSet2D(image,x,y,test);//cvSet2D的使用
2.直接访问:
例如:
IplImage* image = cvCreateImage(cvSize(200,200),IPL_DEPTH_8U,1);
((uchar*)( image->imageData + i*image->widthStep))[j] = 255;
image->imageData:存储图像像素值数组的首地址
image->widthStep:指的是图像每行所占的字节数,这个概念不要和width混淆。(往往因为存储要遵循字节对齐的原则,widthStep并不是单纯的像素数*nChannels,往往会更大一点)
所以因为是单通道的图像,所以(.....)[j]就是(i,j)点的值
3.指针直接访问:
例如:
IplImage* image = cvCreateImage(cvSize(200,200),IPL_DEPTH_8U,1);
int height = image->height;
int width = image->width;
int widthstep = image->widthStep;
uchar* data = (uchar*) image->imageData;
data[i*widthstep+j] = 255;
这种方法感觉像是创建数组指向存储区域,然后对数组操作,省掉了首地址了。我是这么理解的,不知道对不对。
多通道字节图像的访问
1.其实和单通道差不多,只不过通道数变多了,像第一种方法中cvGet2D返回的test就可以取出相对应的bgr通道的值了:test[0],test[1].test[2]。cvSet2D的用法不变
2.直接访问的方式就要加上:
((uchar*)( image->imageData + i*image->widthStep))[j*nChannels+0] = 255;//或者+1,+2分别表示bgr通道的值
3.指针的方式同上一种:
data[i*widthstep+j*nChannels+k] = 255;//k的值为0-通道数
OK,That's all.
第一次写,新手请轻喷!!!
有时间再写绘制函数的笔记好了,内容很少,仅当作自己的复习!!