注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

*^^* 寂寞的whitebaby

欢迎来到我的家,充满回忆的地方

 
 
 

日志

 
 
关于我

いǒDê個性伱惹吥起                 ヤ 無限囂張.習慣寂寞‰〆┈

网易考拉推荐

在OpenCV中用指针访问像素值的一些体会  

2011-02-28 17:05:41|  分类: openCV |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

OpenCV中文站中有一篇关于OpenCV基础操作的文章《OpenCV 编程简介(矩阵/图像/视频的基本读写操作)入门必读》,上面对OpenCV的一些入门操作进行了详细的介绍。我也是看了这篇文章后才开始了OpenCV的编程。但是最近发现了一个理解上的小失误,导致一个问题困扰了很长时间。现在问题解决了,就把思考的过程写在这跟大家分享一下。

该文章其中有一部分是关于如何操作图像像素值的介绍:
基于指针的直接访问:(简单高效)
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;

对像素值的访问,作者用了data[i*step+j]这样的格式,当时没怎么仔细想,就认为这是图像中坐标为(i, j)像素的值,其实并不是这样的。

首先,来看一下IplImage的结构,其中像素值存放在char *imageData指针做指向的区域,OpenCV官方文档中将其解释为"A pointer to the aligned image data",就是指向排列好的图像数据的指针。但是指针取出来,是一个一维数组data[i*step+j],是怎么体现出“排列好的”这个性质的呢?OpenCV用了一个辅助的变量来实现。就是IplImage的widthStep,它表示图像一行有多少个字节。用这个值除以一个像素所占的字节数,就可以得到一行有多少个像素。data[i*step+j]就是第i行第j个像素的像素值(i和j从0开始,这个应该不用我说吧)。

但是,如果用(i, j)来表示坐标的话,正好反了。因为行号是在列的方向递增的。比如说第5行,那么它的纵坐标应该是5-1。第五行的第几个,这个几才代表横坐标。

明白了这点就好办了,如果想用(i, j)同时来表示坐标和数组中的点,那么应该用data[i+j*step]。i在图像宽度范围内递增,j在图像高度范围内递增。如果图像宽和高非别为w和h,那么对像素的遍历可以用下面的循环搞定:
for(int j = 0; j < h; j++) {
    for(int i = 0; i < w; i++) {
        printf("(%d, %d)=%d\t", i, j, data[i+j*step]);
    }
}

以后就定义成data[i+j*step],方便后面的操作。一般情况下还是习惯i在前、j在后的格式。


  评论这张
 
阅读(2291)| 评论(3)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018