/*
毛星云《opencv3编程入门》学习记录,并非原创。
*/
1.图像的存储
图像由像素组成,一幅图像即一个存储众多像素的像素点矩阵。而每个像素又存储了许多数据,没别代表了图像的各个特征。
在opencv中,图像的数据被存储在Mat容器当中。
Mat类数据结构是opencv的主要数据结构,Mat类的存在使使用者无需手动为其分配内存与手动为其释放内存。
Mat的数据包括两部分呢:
矩阵头和一个指向存储所有像素值的矩阵的指针。
矩阵头包括:
矩阵尺寸,存储方式,存储地址等信息。
2.像素值的存储
像素值的存储需要指定颜色空间和数据类型。
1.颜色空间是指针对一个给定的颜色,如何组合颜色元素以对其编码。其中灰度级空间是最简单的,只处理黑白两种颜色以组合出不同的灰色。而彩色则具有多种颜色空间。RGB颜色空间等。
.灰度级空间以对黑,白两种颜色进行组合。
.RGB颜色空间,以红,绿,蓝三原色为基色进行组合,最为常见。
.HSV和HLS把颜色分解成色调,饱和度和亮度/明度。
.YCrCb在JPEG图像格式中广泛使用.
.CIE L*a*b是一种在感知上均匀的颜色空间。适合用来度量两个颜色间的距离。
2.数据类型则决定了一个元素的定义域。
.char(有符号或者无符号)
.float/double
3.像素的操作与颜色缩减
像素操作的三种方法:
1.使用指针
2.使用迭代器
3.使用Mat类的at方法
以图像的颜色缩减为目的,分别使用三种像素操作方法实现:
颜色缩减(能大大降低算法的复杂度):
1.遍历像素矩阵每一个像素;
2.对每一个像素应用公式
/*
时间:2016.4.23
关于opencv学习
图像处理--遍历图像像素 与 颜色缩减实现的几种不同方法
(学习毛星云编著图书记录)
*/
#include <opencv2\opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
void ColorReduceOfPtr(const Mat &srcImage, Mat &dstImage, int div);
void ColorReduceOfIterator(const Mat &srcImage, Mat &dstImage, int div);
void ColorReduceOfAt(const Mat &srcImage, Mat &dstImage, int div);
int main()
{
Mat input = imread("source.jpeg", 1);
if (!input.data)
{
cout << "读取图片失败!" << endl;
exit(EXIT_FAILURE);
}
Mat srcImage;
Mat dstImage;
resize(input, srcImage, Size(0, 0), 0.3, 0.3, 1); //改变图像尺寸
int imageW = srcImage.rows;
int imageH = srcImage.cols;
dstImage.create(Size(imageW, imageH), srcImage.type()); //以srcImage的尺寸构建dstImage
//ColorReduceOfPtr(srcImage, dstImage, 50);
//ColorReduceOfIterator(srcImage, dstImage, 50);
ColorReduceOfAt(srcImage, dstImage, 50);
namedWindow("原始图片窗口", 1);
namedWindow("目标图片窗口", 1);
imshow("原始图片窗口", srcImage);
imshow("目标图片窗口", dstImage);
while ((char)waitKey() != 'q');
return 0;
}
//指针操作像素实现颜色缩减
void ColorReduceOfPtr(const Mat &srcImage, Mat &dstImage, int div)
{
dstImage = srcImage.clone();
int rowNumber = dstImage.rows;
int colNumber = dstImage.cols * srcImage.channels();
//遍历所有元素
for (int i = 0; i < rowNumber; i++)
{
uchar *data = dstImage.ptr<uchar>(i);
for (int j = 0; j < colNumber; j++)
{
data[j] = data[j] / div*div + div / 2;
}
}
}
//迭代器操作像素实现颜色缩减
void ColorReduceOfIterator(const Mat &srcImage, Mat &dstImage, int div)
{
dstImage = srcImage.clone();
Mat_<Vec3b>::iterator it = dstImage.begin<Vec3b>();
Mat_<Vec3b>::iterator itend = dstImage.end<Vec3b>();
for (; it != itend; ++it)
{
(*it)[0] = (*it)[0] / div*div + div / 2;
(*it)[1] = (*it)[1] / div*div + div / 2;
(*it)[2] = (*it)[2] / div*div + div / 2;
}
}
//配合at方法实现颜色缩减
void ColorReduceOfAt(const Mat &srcImage, Mat &dstImage, int div)
{
dstImage = srcImage.clone();
int rowNumber = dstImage.rows;
int colNumber = dstImage.cols;
for (int i = 0; i < rowNumber; i++)
{
for (int j = 0; j < colNumber; j++)
{
dstImage.at<Vec3b>(i, j)[0] =
dstImage.at<Vec3b>(i, j)[0] / div*div + div / 2;
dstImage.at<Vec3b>(i, j)[1] =
dstImage.at<Vec3b>(i, j)[1] / div*div + div / 2;
dstImage.at<Vec3b>(i, j)[2] =
dstImage.at<Vec3b>(i, j)[2] / div*div + div / 2;
}
}
}