zoukankan      html  css  js  c++  java
  • 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地址计算

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

    找的元素的数据类型。

  • 相关阅读:
    垃圾回收相关概念
    垃圾回收相关算法
    垃圾回收概述
    StringTable
    执行引擎
    [前端]背景图,中间放大特效
    [Javascript]类数组对象为什么不能用for in进行遍历
    [前端] 画个圈圈显示百分比
    win10 Build 14905.rs_prerelease.160811-1739 填坑记录
    [翻译][10 By 10 外文博客] 01.uwp获得关注并安装
  • 原文地址:https://www.cnblogs.com/zuoyou151/p/9450117.html
Copyright © 2011-2022 走看看