OpenCv007高效遍历图像

#include<opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
void colorReduce(Mat &image, int div = 64)
{
	int nl = image.rows;
	int nc = image.cols;//;*image.channels();
	if (image.isContinuous())
	{
		nc = nc *nl;
		nl = 1;
	}
	/*因为  这里 少写了 一个log  找了一天的错误*/
	int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0));
	uchar mask = 0xff << n;
	for (int j = 0; j < nl; j++)
	{
		/*这里有一个 疑问  这里定义了一个指向 uchar数据类型的指针 那么指针本身data是几位呢  待会测试一下
		 还有就是这个data是这一行的首地址 */

		/*非常 好奇  传进来 彩色和 灰色 地址都是一样的 并且是连续的  彩色的不是三通道吗  灰色的一个地址可以存取一个值 
		彩色的一个地址可以存下三个通道的值?
		答案 是不能的   一个地址只能存放一个通道的值   
		RGB三个通道 是如何合成一个彩色的像素值呢

		*/
		uchar * data = image.ptr<uchar>(j);
		for (int i = 0; i < nc; i++)
		{
			/*这里傻X了好长时间  在开始写列nc =image.cols 如果这样写 那么循环体内就得按照下面这种方式写
			因为这样才能全部遍历图像  如果只写*data++ = *data & mask + div / 2;这一句 那么只能遍历三分之一的
			图像 可以自己试着看一下   nc =image.cols*image.channels()就可以只写一句了
			*/
			*data++ = *data & mask + div / 2;
			*data++ = *data & mask + div / 2;
		    *data++ = *data & mask + div / 2;
	
			/*data[i] = data[i] & mask + div / 2;
			data[i+1] = data[i+1] & mask + div / 2;
			data[i+2] = data[i+2] & mask + div / 2;
			data++;*/
		}

	}
}
int main()
{
	Mat image;
	image = imread("Test.jpg");
	//(getTickCount())需要加上 括号
	double Time1 = static_cast<double>(getTickCount());
	colorReduce(image);
	Time1 = static_cast<double>(getTickCount()) - Time1;
	Time1 /= getTickFrequency();
	cout << "运行时间:" << Time1 << endl;
	namedWindow("高效遍历图像");
	imshow("高效遍历图像", image);
	waitKey(0);
	return 0;
}
/*
1: *data++  ++和*的优先级相同 遵循自右向左执行的规则  等价于*(data++)  首先引用data的值  实现*data的运算  再使data+1
2:输出单个像素时  cout<<int(*data++);  要在前面加上 强制类型转换  否则输出乱码
3:了解记住 时间是怎么计算的 前一篇文章中 就是不理解 才出错
*/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值