扫描图像
扫描图像有四种方法:C指针访问方法、迭代器方法、即时地址计算方法、LUT函数。实现方法及用时比较可参考下方代码。
参考链接:https://docs.opencv.org/master/db/da5/tutorial_how_to_scan_images.html
颜色空间缩减算法
将现有颜色空间值除以某个输入值,以获得较少的颜色数。例如,颜色值0到9可取为新值0,10到19可取为10,以此类推。其公式为:
简单的颜色空间缩小算法包括遍历图像矩阵的每个像素以及应用上述公式。值得注意的是,乘除法运算对于系统来说是昂贵的。如果可以,尽量通过使用更简单的操作(如加减法等)来避免这种情况。
因此,对于较大的图像,预先计算所有可能的值,并且通过使用查找表来进行分配。查找表是简单的数组(一个或多维),对于给定的输入值变量保存最终的输出值。其优点在于不需要进行计算,而直接读取结果。
其实查询表的实质就是:把图像中的数据从之前的比较高的灰度级降下来,例如灰度级是256的char类型的灰度级,通过一个参数(例如10),将原来的256个灰度级降到了26个灰度级,原来图像中灰度值在0-9的数据现在灰度值变成了0,原来灰度值为11-19的图像数据现在灰度值变为了1,以此类推,250-256的灰度值就变为了25。所以通过参数10,图像的灰度级就降到了26。
计时
OpenCV提供了两个简便的可用于计时的函数 getTickCount() 和 getTickFrequency() 。第一个函数返回CPU自某个事件(如启动电脑)以来走过的时钟周期数,第二个函数返回CPU一秒钟所走的时钟周期数,便于换算成以秒为单位,对运算方法进行计时统计。
#include <opencv2/core.hpp>
#include <opencv2/core/utility.hpp>
#include "opencv2/imgcodecs.hpp"
#include <opencv2/highgui.hpp>
#include <iostream>
#include <sstream>
// sstream定义了istringstream、ostringstream和stringstream,
// 分别用来进行流的输入、输出和输入输出操作
using namespace std;
using namespace cv;
Mat& ScanImageAndReduceC(Mat& I, const uchar* table);
Mat& ScanImageAndReduceIterator(Mat& I, const uchar* table);
Mat& ScanImageAndReduceRandomAccess(Mat& I, const uchar* table);
int main(int argc, char* argv[])
{
Mat I, J;
String imageName("../data/lena.jpg");
char ch = NULL;
cout << "If U want grayscale,please enter G ! Or any key !" << endl;
ch = getchar();
if (ch == 'G')
I = imread(imageName, IMREAD_GRAYSCALE); // 灰度图像
else
I = imread(imageName, IMREAD_COLOR); // 彩色图像
if (I.empty())