opencv 读取像素值

话不多说,新手在不断学习,刚刚看见读取每个像素点值很是好奇。
#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, intidx ); 
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成员有:

  1. int  nSize;           
  2.         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排列如下:         

 
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

虽然第一种跟第二种的时间复杂度是相同的。但是第二种的速度明显比第一种快很多。

追求速度就选用第二种!



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值