图像遍历
遍历图像的4种方式:
一 at
Mat类提供了一个at的方法用于取得图像上的点,它是一个模板函数,可以取到任何类型的图像上的点。下面我们通过一个图像处理中的实际来说明它的用法。
在实际应用中,我们很多时候需要对图像降色彩,因为256256256实在太多了,在图像颜色聚类或彩色直方图时,我们需要用一些代表性的颜色代替丰富的色彩空间,我们的思路是将每个通道的256种颜色用64种代替,即将原来256种颜色划分64个颜色段,每个颜色段取中间的颜色值作为代表色。
void colorReduce(Mat& image,int div)
{
for(int i=0;i<image.rows;i++)
{
for(int j=0;j<image.cols;j++)
{
image.at(i,j)[0]=image.at(i,j)[0]/divdiv+div/2;
image.at(i,j)[1]=image.at(i,j)[1]/divdiv+div/2;
image.at(i,j)[2]=image.at(i,j)[2]/div*div+div/2;
}
}
}
更简单一些的方法:OpenCV定义了一个Mat的模板子类为Mat_,它重载了operator()让我们可以更方便的取图像上的点。
Mat_ im=image;
im(i,j)=im(i,j)/div*div+div/2;
二 高效一点:用指针来遍历图像
void colorReduce(const Mat& image,Mat& outImage,int div)
{
// 创建与原图像等尺寸的图像
outImage.create(image.size(),image.type());
int nr=image.rows;
// 将3通道转换为1通道
int nl=image.colsimage.channels();
for(int k=0;k<nr;k++)
{
// 每一行图像的指针
const uchar inData=image.ptr(k);
uchar* outData=outImage.ptr(k);
for(int i=0;i<nl;i++)
{
outData[i]=inData[i]/div*div+div/2;
}
}
}
三、更高效的方法
一般来说图像行与行之间往往存储是不连续的,但是有些图像可以是连续的,Mat提供了一个检测图像是否连续的函数isContinuous()。当图像连通时,我们就可以把图像完全展开,看成是一行。
void colorReduce(const Mat& image,Mat& outImage,int div)
{
int nr=image.rows;
int nc=image.cols;
outImage.create(image.size(),image.type());
if(image.isContinuous()&&outImage.isContinuous())
{
nr=1;
nc=ncimage.rowsimage.channels();
}
for(int i=0;i<nr;i++)
{
const uchar* inData=image.ptr(i);
uchar* outData=outImage.ptr(i);
for(int j=0;j<nc;j++)
{
*outData++=inData++/divdiv+div/2;
}
}
}
用指针除了用上面的方法外,还可以用指针来索引固定位置的像素:
image.step返回图像一行像素元素的个数(包括空白元素),image.elemSize()返回一个图像像素的大小。
&image.at(i,j)=image.data+iimage.step+jimage.elemSize();
四、 用迭代器来遍历
void colorReduce(const Mat& image,Mat& outImage,int div)
{
outImage.create(image.size(),image.type());
MatConstIterator_ it_in=image.begin();
MatConstIterator_ itend_in=image.end();
MatIterator_ it_out=outImage.begin();
MatIterator_ itend_out=outImage.end();
while(it_in!=itend_in)
{
(*it_out)[0]=(it_in)[0]/divdiv+div/2;
(*it_out)[1]=(it_in)[1]/divdiv+div/2;
(*it_out)[2]=(it_in)[2]/divdiv+div/2;
it_in++;
it_out++;
}
}
本文介绍了4种遍历OpenCV中Mat图像的方法,包括使用at方法、Mat_的operator()、指针以及迭代器。针对图像降色彩的应用场景,提供了代码示例,展示如何将每个通道的256种颜色用64种代替。其中,利用图像连续性判断的第三种方法在效率上最高。

1881

被折叠的 条评论
为什么被折叠?



