【Opencv】图像扫描

<span style="font-size:48px;color:#cc66cc;">ColorReduce</span>

void colorReduce(cv::Mat image, int div)  

彩色图像由三个通道像素组成(RGB),因此颜色总数为256*256*256。为了降低分析的复杂性,可以通过colorReduce函数把每种颜色数量减少8倍,则颜色总数变成32*32*32。因此基本的减色算法很简单,假设N是减色因子,则代码实现就是简单的value/N*N,可以得到N的倍数,并且刚好不超过原始像素值。只需加上N/2就得到相邻的N倍数之间的中间值。最后对所有8位通道值重复这个过程,就会得到(256/N)*(256/N)*(256/N)种可能的颜色值。


 

                                 (a)原始图像                                                                                            (b)ColorReduce64倍

方法一:.ptr和数组操作

<span style="background-color: rgb(255, 255, 255);"><span style="font-family:Times New Roman;font-size:18px;">void colorReduce1(cv::Mat &image, int div = 64) {    //64是减色因子

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

	for (int j = 0; j<nl; j++) {

		uchar* data = image.ptr<uchar>(j);//访问图像中一个行地址就用.ptr

		for (int i = 0; i<nc; i++) {

			// process each pixel ---------------------

			data[i] = data[i] / div*div + div / 2;

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

		} // end of line                   
	}
}</span></span>

方法二:.ptr和指针操作*++

<span style="font-family:Times New Roman;font-size:18px;">void colorReduce2(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

	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 / div*div + div / 2;

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

		} // end of line                   
	}
}</span>


方法三:.ptr,指针操作*++和位运算
<span style="font-family:Times New Roman;font-size:18px;">void colorReduce3(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
	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                   
	}
}</span>

方法四:Mat迭代器

<span style="font-family:Times New Roman;font-size:18px;">void colorReduce4(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 ----------------
	}
}</span>

方法五:.at 图像坐标
<span style="font-family:Times New Roman;font-size:18px;font-weight: normal;">void colorReduce5(cv::Mat &image, int div = 64) {

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

	for (int j = 0; j<nl; j++) {
		for (int i = 0; i<nc; i++) {

			// process each pixel ---------------------

			image.at<cv::Vec3b>(j, i)[0] = image.at<cv::Vec3b>(j, i)[0] / div*div + div / 2;
			image.at<cv::Vec3b>(j, i)[1] = image.at<cv::Vec3b>(j, i)[1] / div*div + div / 2;
			image.at<cv::Vec3b>(j, i)[2] = image.at<cv::Vec3b>(j, i)[2] / div*div + div / 2;

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

		} // end of line                   
	}
}</span>

方法六:创建输出图像

<pre name="code" class="cpp"><span style="font-family:Times New Roman;font-size:18px;font-weight: normal;">void colorReduce6(const cv::Mat &image, // input image 
	cv::Mat &result,      // output image
	int div = 64) {

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

	// allocate output image if necessary
	result.create(image.rows, image.cols, image.type());

	// created images have 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 = result.ptr<uchar>(j);
		const uchar* idata = image.ptr<uchar>(j);

		for (int i = 0; i<nc; i++) {

			// process each pixel ---------------------

			*data++ = (*idata++)&mask + div / 2;
			*data++ = (*idata++)&mask + div / 2;
			*data++ = (*idata++)&mask + div / 2;

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

		} // end of line                   
	}
}</span>

方法七:重载操作

<span style="font-family:Times New Roman;font-size:18px;font-weight: normal;">void colorReduce7(cv::Mat &image, int div = 64) {

	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

	// perform color reduction
	image = (image&cv::Scalar(mask, mask, mask)) + cv::Scalar(div / 2, div / 2, div / 2);
}</span>


 
 



 

     


























评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值