OpenCV_Function

图像操作

遍历图像的四种方式

  1. at<typename>(i,j)

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

1
2
3
4
5
6
7
8
9
void colorReduce(Mat& image,int div){
for(int i=0;i<image.rows;i++){
for(int j=0;j<image.cols;j++){
image.at<Vec3b>(i,j)[0]=image.at<Vec3b>(i,j)[0]/div*div+div/2;
image.at<Vec3b>(i,j)[1]=image.at<Vec3b>(i,j)[1]/div*div+div/2;
image.at<Vec3b>(i,j)[2]=image.at<Vec3b>(i,j)[2]/div*div+div/2;
}
}
}
  1. 用指针来遍历图像

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 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;k<nr;k++){
10 // 每一行图像的指针
11 const uchar* inData=image.ptr<uchar>(k);
12 uchar* outData=outImage.ptr<uchar>(k);
13 for(int i=0;i<nl;i++){
15 outData[i]=inData[i]/div*div+div/2;
16 }
17 }
18 }
  1. 使用迭代器来遍历图像
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 1 void colorReduce(const Mat& image,Mat& outImage,int div)
2 {
3 outImage.create(image.size(),image.type());
4 MatConstIterator_<Vec3b> it_in=image.begin<Vec3b>();
5 MatConstIterator_<Vec3b> itend_in=image.end<Vec3b>();
6 MatIterator_<Vec3b> it_out=outImage.begin<Vec3b>();
7 MatIterator_<Vec3b> itend_out=outImage.end<Vec3b>();
8 while(it_in!=itend_in)
9 {
10 (*it_out)[0]=(*it_in)[0]/div*div+div/2;
11 (*it_out)[1]=(*it_in)[1]/div*div+div/2;
12 (*it_out)[2]=(*it_in)[2]/div*div+div/2;
13 it_in++;
14 it_out++;
15 }
16 }
  1. 最高效的方法

当不对行进行填补的时候,图像可被视为一个长为W x H的一维数组。用isContinuous来判断是否对行进行的填补。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int n1 = image.rows;
int nc = image.cols * image.channels();
ifimage.isContinuous())//判断是否对行有额外的填补像素,返回值为真,则没有填补。
{
nc = nc * n1;
n1 = 1;
}
forint i = 0; i <n1; i ++)//若图像是连续的,则只循环一次
{
uchar * data = image.ptr <uchar>(i);
forint j = 0; j <nc; j ++)
{
data [j] = 0;
}
}
打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2019-2022 guoben
  • PV: UV:

微信