颜色缩减:
“颜色缩减”的作用是减少图像内部使用的色彩数目,包括创建调色板和用调色板中与图像上最接近的颜色替换位图颜色。
/**
* @file 2_3.cpp
* @Synopsis
* @author weih.cao
* @version 1.0.0.0
* @date 2013-12-08
*/
#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
/* --------------------------------------------------------------------------*/
/**
* @Synopsis colorReduce
*
* @Param image
* @Param div
*/
/* ----------------------------------------------------------------------------*/
void colorReduce(cv::Mat &image,int div=64)
{
int nl = image.rows;//行数
int nc = image.cols*image.channels();//每行的像素个数=列数*通道数
for(int j = 0; j < nl; j++)
{
//得到j行的首地址
uchar* data = image.ptr<uchar>(j);
for (int i =0; i < nc; i++)
{
//处理每一个像素
data[i] = data[i]/div*div+div/2;
}
}
}
int main(int argc, char** argv)
{
cv::Mat img = cv::imread(argc == 2 ? argv[1] : "lena.jpg");
colorReduce(img);
cv::namedWindow("Image");
cv::imshow("Image", img);
cv::waitKey(0);
}
原理:
彩色图像中,缓冲区的前三个字节对应图像左上角的三个通道值,接下来三个字节对应第一行第二个像素...
一个宽为W,高为H的图像需要的内存大小为W*H*3个uchar构成的内存块。cols代表图像的宽度(列数),rows代表图像的高度,step代表以字节为单位单位的的图像的有效宽度。即使图像的元素类型不是uchar,step仍代表行的字节数。图像的通道数可以由channels方法得到:灰度图像1,彩色图像3。
每行的像素值数为:
int nc = image.cols*image.channels();
cv::Mat提供了ptr函数返回任意行的首地址:
uchar* data= image.ptr<uchar>(j);
既然是指针运算所以也可以通过++操作从一列移到下一列。
效果图: