话不多说,新手在不断学习,刚刚看见读取每个像素点值很是好奇。
#include <highgui.h>
#include <iostream>
using namespace std;
int main()
{
IplImage* src = cvLoadImage("e:/11.bmp",CV_LOAD_IMAGE_COLOR);
//方法一:
CvScalar s = cvGet2D(src,200,201);//获取像素点为(201,200)点的BGR的值
//注:此处的x,y值是反的,具体不解释
cout<<s.val[0]<<'\t'<<s.val[1]<<'\t'<<s.val[2]<<endl;//输出B值,G值,R值
//方法二:此处输出的时候进行强制类型转换就可以得到和上面一样的值。不能直接输出uchar?
//坐标(200,201)的像素值
cout<<(int)((uchar*)(src->imageData+200*src->widthStep))[3*201]<<endl;
cout<<(int)((uchar*)(src->imageData+200*src->widthStep))[3*201+1]<<endl;
cout<<(int)((uchar*)(src->imageData+200*src->widthStep))[3*201+1]<<endl;
cvReleaseImage(&src);
return 0;
}
*************************************************************
http://wenku.baidu.com/view/5cc06af8910ef12d2af9e74c.html(参考百度文库)
1.使用cvGet2D()函数访问:
cvGet*D系列函数可以用来返回特定位置的数组元素(一般使用cvGet2D),原型如下:
CvScalar cvGet1D( const CvArr* arr, int idx0 );
CvScalar cvGet2D( const CvArr* arr, int idx0, int idx1 )
CvScalar cvGet3D( const CvArr* arr, int idx0, int idx1, int idx2 );
CvScalar cvGetND( const CvArr* arr, int* idx );
idx0,idx1,idx2分别用来指示元素数组下标,即cvGet2D返回(idx0,idx1)处元素的值。
可以通过如下方法访问一个图片的所有像素点:
假设图像加载完毕!
CvScalar t1,t2;
for(int i = 0;i < img->height;i++)
{
for(int j = 0;j < img->width;j++)
{
t2=cvGet2D(img,i,j);
此时t2中的值就是当前像素点rgb值,注意此时的t2.val[0]为b通道
t2.val[1]为g
t2.val[2]为r
此时就能获取当前像素点的bgr了。
可以通过如下方式更改当前像素点的rgb通道值。
t1.val[0]=0; b
t1.val[1]=0; g
t1.val[2]=0; r
cvSet2D(img,i,j,t1);
}
不过通过上诉方法在速度方面会比较慢。可以通过如下方法加快访问,更改速度。
2.直接访问:
Iplimage成员有:
-
int nSize;
-
- int ID;
- int nChannels;
- int alphaChannel;
- int depth;
- char colorModel[4];
- char channelSeq[4];
- int dataOrder;
- int origin;
- int align;
- int width;
- int height;
- struct _IplROI *roi;
- struct _IplImage *maskROI;
- void *imageId;
- struct _IplTileInfo *tileInfo;
- int imageSize;
- char *imageData;
- int widthStep;
- int BorderMode[4];
- int BorderConst[4];
- char *imageDataOrigin;
比较重要的两个元素是:char *imageData以及widthStep。imageData存放图像像素数据,而widStep类似CvMat中的step,表示以字节为单位的行数据长度。
多通道(三通道)字节图像中,imageData排列如下: ![Opencv遍历每个像素点](https://img-my.csdn.net/uploads/201205/11/1336720474_2062.png)
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
uchar* data=(uchar *)img->imageData;
int step = img->widthStep/sizeof(uchar); step即为上图的widthstep
int channels = img->nChannels; 这个图片为3通道的
uchar *b,*g,*r;
for(int i=0;iheight;i++)
for(int j=0;jwidth;j++){
*b=data[i*step+j*chanels+0]; 此时可以通过更改bgr的值达到访问效果。
*g=data[i*step+j*chanels+1];
*r=data[i*step+j*chanels+2];
}
i*step 当i=0 即为上图的第一行 为1就是第二行
j*chanels+0 j*通道数当j=0为第一列的第0个通道->b
j*channels+1 当j=1为第二列的第1个通道->g
虽然第一种跟第二种的时间复杂度是相同的。但是第二种的速度明显比第一种快很多。
追求速度就选用第二种!