opencv 3.0 Mat遍历:指针和STL

优化OpenCV中自然图像颜色减少算法
本文探讨了在OpenCV中通过高效遍历和STL简化实现自然图像颜色减少的技术,包括指针遍历优化和使用Mat_类提高性能。通过减少循环跳转和利用连续内存布局,算法实现了显著的加速。

一. opencv 中的高效遍历自然是指针遍历

 

先上最优的代码

以下实例是参考OPENCV书上的

功能:像素颜色减少

1. 当数据存储内有补齐,是连续的。则使用指针统一遍历

2. 当多通道,内循环顺次处理3通道。减少循环的跳转。

// using .ptr and * ++ and bitwise (continuous+channels)
void colorReduce(cv::Mat &image, int div=64) {

	  int nl= image.rows; // number of lines
	  int nc= image.cols ; // number of columns

	  if (image.isContinuous())  {
		  // then no padded pixels
		  nc= nc*nl; 
		  nl= 1;  // it is now a 1D array
	   }

	  int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
	  // mask used to round the pixel value
	  uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0
              
      for (int j=0; j<nl; j++) {

		  uchar* data= image.ptr<uchar>(j);

          for (int i=0; i<nc; i++) {
 
            // process each pixel ---------------------
                 
            *data++= *data&mask + div/2;
            *data++= *data&mask + div/2;
            *data++= *data&mask + div/2;
 
            // end of pixel processing ----------------
 
            } // end of line                   
      }
}

 

相比以下的代码,上面的快10%

// using .ptr and * ++ and bitwise (continuous)
void colorReduce(cv::Mat &image, int div=64) {

	  int nl= image.rows; // number of lines
	  int nc= image.cols * image.channels(); // total number of elements per line

	  if (image.isContinuous())  {
		  // then no padded pixels
		  nc= nc*nl; 
		  nl= 1;  // it is now a 1D array
	   }

	  int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
	  // mask used to round the pixel value
	  uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0
              
      for (int j=0; j<nl; j++) {

		  uchar* data= image.ptr<uchar>(j);

          for (int i=0; i<nc; i++) {
 
            // process each pixel ---------------------
                 
            *data++= *data&mask + div/2;
 
            // end of pixel processing ----------------
 
            } // end of line                   
      }
}


二. 简洁的遍历自然是 STL

先上最优的代码

使用了模板Mat_  不仅简洁书写(不用写数据类型了),还加快效率。

// using MatIterator_ 
void colorReduce(cv::Mat &image, int div=64) {

	  // get iterators
	  cv::Mat_<cv::Vec3b> cimage= image;
	  cv::Mat_<cv::Vec3b>::iterator it=cimage.begin();
	  cv::Mat_<cv::Vec3b>::iterator itend=cimage.end();

	  for ( ; it!= itend; it++) { 
        
		// process each pixel ---------------------

        (*it)[0]= (*it)[0]/div*div + div/2;
        (*it)[1]= (*it)[1]/div*div + div/2;
        (*it)[2]= (*it)[2]/div*div + div/2;

        // end of pixel processing ----------------
	  }
}

相比以下的代码,上面的快2%

// using Mat_ iterator 
void colorReduce(cv::Mat &image, int div=64) {

	  // get iterators
	  cv::Mat_<cv::Vec3b>::iterator it= image.begin<cv::Vec3b>();
	  cv::Mat_<cv::Vec3b>::iterator itend= image.end<cv::Vec3b>();

	  for ( ; it!= itend; ++it) {
        
		// process each pixel ---------------------

        (*it)[0]= (*it)[0]/div*div + div/2;
        (*it)[1]= (*it)[1]/div*div + div/2;
        (*it)[2]= (*it)[2]/div*div + div/2;

        // end of pixel processing ----------------
	  }
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值