Core组件进阶
颜色空间缩减
颜色空间缩减:将现有的颜色空间值除以某个输入值,以获得较少的颜色数。(对于多通道图像而言颜色数太多了)。如以10为除数,10-19为10,20-29为20.
处理图像像素时,每个像素都进行一遍上述的操作。但其实只有0-255即256种情况,可以提前将256种计算好的结果存在表里,这样直接取结果即可。
int divideWith = 10;
uchar table[256];
for(int i = 0;i<256;i++){
table[i] = divideWith * (i/divideWith);
}//table表中存放的是值为i像素减少颜色空间的结果
LUT函数
look up table。用来查表
批量进行图像查找、扫描与操作图像
Mat lookUpTable(1,256,CV_8U);
uchar *p = lookUpTable.data;
for(int i = 0;i<256;i++){
p[i] = table[i];
}
for(int i = 0;i<times;i++){
LUT(I,lookUpTable,J);//I输入,J输出
}
计时函数
getTickCount():返回cpu自某个事件以来走过的时钟周期
getTickFrequency():返回CPU1秒钟所走的时钟周期数
double time0 = static_cast<double>(getTickCount());
//处理事件
time0 = ((double)getTickCount()-time0)/getTickFrequency();
cout<<"花费时间"<<time0<<endl;
访问图像中的像素
对于颜色较多的情况,比如有256种颜色,我们希望有64种,那么只需要将原来的颜色除以4,以后再乘以4即可.
下面给出的各例子为对图像中的像素进行缩减。
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace std;
using namespace cv;
void colorReduce(Mat& inputImage, Mat& outputImage, int div);
int main()
{
//【1】创建原始图并显示
Mat srcImage = imread("1.jpg");
imshow("原始图像", srcImage);
//【2】按原始图的参数规格来创建创建效果图
Mat dstImage;
dstImage.create(srcImage.rows, srcImage.cols, srcImage.type());//效果图的大小、类型与原图片相同
//【3】记录起始时间
double time0 = static_cast<double>(getTickCount());
//【4】调用颜色空间缩减函数
colorReduce(srcImage, dstImage, 32);
//【5】计算运行时间并输出
time0 = ((double)getTickCount() - time0) / getTickFrequency();
cout << "\t此方法运行时间为: " << time0 << "秒" << endl; //输出运行时间
//【6】显示效果图
imshow("效果图", dstImage);
waitKey(0);
}
用指针访问像素
//---------------------------------【colorReduce( )函数】---------------------------------
// 描述:使用【指针访问:C操作符[ ]】方法版的颜色空间缩减函数
//----------------------------------------------------------------------------------------------
void colorReduce(Mat& inputImage, Mat& outputImage, int div)//div=32
{
//参数准备
outputImage = inputImage.clone(); //拷贝实参到临时变量
int rowNumber = outputImage.rows; //行数
int colNumber = outputImage.cols * outputImage.channels();
//列数 x 通道数=每一行元素的个数
//双重循环,遍历所有的像素值
for (int i = 0; i < rowNumber; i++) //行循环
{
uchar* data = outputImage.ptr<uchar>(i); //获取第i行的首地址
for (int j = 0; j < colNumber; j++) //列循环
{
// ---------【开始处理每个像素】-------------
data[j] = data[j] / div * div + div / 2;
// ----------【处理结束】---------------------
} //行处理结束
}
}
Mat的公有变量cols和rows获取图像的宽和高,成员函数channels()返回图像的通道数。灰度图通道数为1,彩色图通道数为3
每行的像素 = 列数 x 通道数
Mat类中的ptr函数可以得到任意行的首地址。返回第i行的首地址
data[j] = data[j] / div * div + div / 2;
//等价于
*data++ = *data/div*div+div/2;