aihot  2017-05-08 16:04:23  OpenCV |   查看评论   

 OpenCV成长之路(2):图像的遍历

我们在实际应用中对图像进行的操作,往往并不是将图像作为一个整体进行操作,而是对图像中的所有点或特殊点进行运算,所以遍历图像就显得很重要,如何高效的遍历图像是一个很值得探讨的问题。

一、遍历图像的4种方式:at<typename>(i,j)

Mat类提供了一个at的方法用于取得图像上的点,它是一个模板函数,可以取到任何类型的图像上的点。下面我们通过一个图像处理中的实际来说明它的用法。

在实际应用中,我们很多时候需要对图像降色彩,因为256*256*256实在太多了,在图像颜色聚类或彩色直方图时,我们需要用一些代表性的颜色代替丰富的色彩空间,我们的思路是将每个通道的256种颜色用64种代替,即将原来256种颜色划分64个颜色段,每个颜色段取中间的颜色值作为代表色。

 1 void colorReduce(Mat& image,int div)  2 {  3     for(int i=0;i<image.rows;i++)  4     {  5         for(int j=0;j<image.cols;j++)  6         {  7             image.at<Vec3b>(i,j)[0]=image.at<Vec3b>(i,j)[0]/div*div+div/2;  8             image.at<Vec3b>(i,j)[1]=image.at<Vec3b>(i,j)[1]/div*div+div/2;  9             image.at<Vec3b>(i,j)[2]=image.at<Vec3b>(i,j)[2]/div*div+div/2; 10         } 11     } 12 }
OpenCV成长之路(2):图像的遍历

 

通过上面的例子我们可以看出,at方法取图像中的点的用法:

image.at<uchar>(i,j):取出灰度图像中i行j列的点。

image.at<Vec3b>(i,j)[k]:取出彩色图像中i行j列第k通道的颜色点。其中uchar,Vec3b都是图像像素值的类型,不要对Vec3b这种类型感觉害怕,其实在core里它是通过typedef Vec<T,N>来定义的,N代表元素的个数,T代表类型。

更简单一些的方法:OpenCV定义了一个Mat的模板子类为Mat_,它重载了operator()让我们可以更方便的取图像上的点。

Mat_<uchar> im=image;

im(i,j)=im(i,j)/div*div+div/2;

二、高效一点:用指针来遍历图像

上面的例程中可以看到,我们实际喜欢把原图传进函数内,但是在函数内我们对原图像进行了修改,而将原图作为一个结果输出,很多时候我们需要保留原图,这样我们需要一个原图的副本。

 1 void colorReduce(const Mat& image,Mat& outImage,int div)  2 {  3     // 创建与原图像等尺寸的图像
 4     outImage.create(image.size(),image.type());  5     int nr=image.rows;  6     // 将3通道转换为1通道
 7     int nl=image.cols*image.channels();  8     for(int k=0            
 1/4    1 2 3 4 下一页 尾页
 

除特别注明外,本站所有文章均为 赢咖4注册 原创,转载请注明出处来自OpenCV成长之路(2):图像的遍历

留言与评论(共有 0 条评论)
   
验证码:
[lianlun]1[/lianlun]