opencv学习笔记2--存取图像元素

最近了解了下如何存取图像元素,在这里归纳总结下,也是记录下,以后需要的时候可以复习下。


假设需要读取在i行j列像点的第k通道. 其中, 行数i的范围为[0, height-1], 列数j的范围为[0, width-1], 通道k的范围为[0, nchannels-1].

 

1.间接存取: (比较通用, 但效率低, 可读取任一类型图像数据)

对单通道字节图像:

IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
CvScalar s;
s=cvGet2D(img,i,j); // get the (i,j) pixel value
printf("intensity=%f\n",s.val[0]);
s.val[0]=111;
cvSet2D(img,i,j,s); // set the (i,j) pixel value

对多通道浮点或字节图像:

IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
CvScalar s;
s=cvGet2D(img,i,j); // get the (i,j) pixel value
printf("B=%f, G=%f, R=%f\n",s.val[0],s.val[1],s.val[2]);
s.val[0]=111;
s.val[1]=111;
s.val[2]=111;
cvSet2D(img,i,j,s); // set the (i,j) pixel value

2.直接存取: (效率高, 但容易出错)

对单通道字节图像:

IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
((uchar *)(img->imageData + i*img->widthStep))[j]=111;

对多通道字节图像:

IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels +0]=111; // B
((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels +1]=112; // G
((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels +2]=113; // R

对多通道浮点图像:

IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
((float *)(img->imageData + i*img->widthStep))[j*img->nChannels +0]=111; // B
((float *)(img->imageData + i*img->widthStep))[j*img->nChannels +1]=112; // G
((float *)(img->imageData + i*img->widthStep))[j*img->nChannels +2]=113; // R

3.用指针直接存取 : (在某些情况下简单高效)

对单通道字节图像:

IplImage* img      =cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
int height        = img->height;
int width         = img->width;
int step           = img->widthStep/sizeof(uchar);
uchar* data        =(uchar *)img->imageData;
data[i*step+j] = 111;

对多通道字节图像:

IplImage* img      =cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
int height        = img->height;
int width         = img->width;
int step           = img->widthStep/sizeof(uchar);
int channels       =img->nChannels;
uchar* data        =(uchar *)img->imageData;
data[i*step+j*channels+k] = 111;

对单通道浮点图像(假设用4字节调整):

IplImage* img      =cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
int height        = img->height;
int width         = img->width;
int step           = img->widthStep/sizeof(float);
int channels       =img->nChannels;
float * data        =(float *)img->imageData;
data[i*step+j*channels+k] = 111;

4.使用 c++ wrapper 进行直接存取: (简单高效)

对单/多通道字节图像,多通道浮点图像定义一个 c++ wrapper:

template<class T> classImage
{
      private:
      IplImage* imgp;
      public:
      Image(IplImage* img=0){imgp=img;}
      ~Image(){imgp=0;}
      void operator=(IplImage*img) {imgp=img;}
      inline T*operator[](const int rowIndx) {
        return ((T*)(imgp->imageData + rowIndx*imgp->widthStep));}
};
typedef struct{
      unsigned char b,g,r;
} RgbPixel;
typedef struct{
      float b,g,r;
} RgbPixelFloat;
typedef Image<RgbPixel>           RgbImage;
typedef Image<RgbPixelFloat>      RgbImageFloat;
typedef Image<unsigned char>      BwImage;
typedefImage<float>              BwImageFloat;

单通道字节图像:

IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
BwImage imgA(img);
imgA[i][j] = 111;

多通道字节图像:

IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
RgbImage      imgA(img);
imgA[i][j].b = 111;
imgA[i][j].g = 111;
imgA[i][j].r = 111;

多通道浮点图像:

IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
RgbImageFloat imgA(img);
imgA[i][j].b = 111;
imgA[i][j].g = 111;
imgA[i][j].r = 111;


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

spearhead_cai

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值