1.2OpenCV如何扫描图像,利用查找表和计时

查找表

颜色缩减法:如果矩阵元素存储的是单通道像素,使用C或C++的无符号字符类型,那么像素可有256个不同值。

但若是三通道图像,这种存储格式的颜色数就太多了(确切地说,有一千六百多万种)。用如此之多的颜色可能

会对我们的算法性能造成严重影响。其实有时候,仅用这些颜色的一小部分,就足以达到同样效果。

这种情况下,一种常用的做法是,颜色空间缩减,将现有颜色空间值除以某个值,以获得较少的颜色数。

                Inew=(Iold/10)*10

简单的颜色空间缩减可由下面两部分组成:1.遍历图像矩阵的每一个像素 2.对像素应用上述公式。 在这个过程中

用到了乘法和除法,而这两种运算又特别费时,所以应尽可能用代价较低的加减或赋值替代。这时,可以预先计

算出所有可能的值,然后需要这些值的时候,利用查找表赋值即可。查找表是一维或多维数组,存储了不同输入

值所对应的输出值,其优势在于只需读取、无需计算。

void CreateLookupTable(uchar* table, uchar divideWith) {
	for (int i = 0; i < 256; i++) {
		table[i] = (i / divideWith)*divideWith;
	}
}

  

图像扫描

1.Efficient Way

 

Mat& ScanImageAndReduceC(Mat& I, const uchar* table) {
	//检测只能为uchar类型
	CV_Assert(I.depth() != sizeof(uchar));
	int channels = I.channels();

	int nRows = I.rows*channels;
	int nCols = I.cols;
	if (I.isContinuous()) {
		nCols*= nRows;
		nRows = 1;
	}
	int i, j;
	uchar *p;
	for (i = 0; i < nRows; ++i) {
		p = I.ptr<uchar>(i);
		for (j = 0; j < nCols; ++j) {
			p[j] = table[p[j]];
		}
	}
	return I;
}

  这里p是图像矩阵的第i行指针,p[j]即是图像的第i行第j列的像素值。获取每一行开始处指针,然后遍历至行末,

如果矩阵是连续存储的,只需请求一次指针然后一路遍历下去。

2.The Iterator Method

获取图像的Begin和End然后增加迭代,直至从begin到end。

Mat& ScanImageAndReduceIterator(Mat& I, const uchar* table) {
	CV_Assert(I.depth() != sizeof(uchar));
	const int channels = I.channels();
	switch (channels) {
	case 1: {
		MatIterator_<uchar>it, end;
		for (it = I.begin<uchar>(), end = I.end<uchar>(); it != end; ++it) {
			*it = table[*it];
		}
		break;
	}
	case 3: {
		MatIterator_<Vec3b>it, end;
		for (it = I.begin<Vec3b>(), end = I.end<Vec3b>(); it != end; ++it) {
			(*it)[0] = table[(*it)[0]];
			(*it)[1] = table[(*it)[1]];
			(*it)[2] = table[(*it)[2]];
		}
	}
	}
	return I;
}

  对于彩色图像中的一行,每一列中有三个uchar元素,这可以认为是一个小的包含uchar元素的vector。在openCV中用Vec3b来命名。

如果要访问第n的子列,只需用简单的[]操作就可以。需要指出的是,OpenCV的迭代在扫描过一行中所有列后会自动跳至下一行,所以

说如果在彩色图像中如果只使用一个简单的 uchar 而不是 Vec3b 迭代的话就只能获得蓝色通道(B)里的值。

3.通过相关返回值的On-the-fly地址计算

这个方法本身用户获取或更改图像中的随机元素。它的基本用途是要确定你试图访问的元素的所在行数与列数。需要自己制定好所要查

找的元素的数据类型。

转载于:https://www.cnblogs.com/zuoyou151/p/9450117.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值