實驗目的:
通過顏色壓縮(color reduction)示例理解學習OpenCV中遍歷圖像的三種方法;
實驗代碼:
#include<opencv2/opencv.hpp>
#include<iostream>
#include<cmath>
using namespace cv;
using namespace std;
// 1:使用指針遍歷圖像
void colorReduceByPointer(Mat& image, int div = 64)
{
int nRows = image.rows;
int nCols = image.cols * image.channels();
if (image.isContinuous())
{
nCols *= nRows;
nRows = 1; // 如果連續,外層循環執行只需一次,以此提高執行效率
}
for (int i = 0; i < nRows; ++i)
{
uchar* data = image.ptr<uchar>(i);
for (int j = 0; j < nCols; ++j)
{
data[j] = data[j] / div*div + div / 2;
}
}
}
// 2:使用at遍歷圖像
void colorReduceByAtMethod(Mat& image, int div = 64)
{
int nRows = image.rows;
int nCols = image.cols;
if (image.channels() == 1)
{
for (int i = 0; i < nRows; ++i)
{
for (int j = 0; j < nCols; ++j)
{
image.at<uchar>(i, j) = image.at<uchar>(i, j) / div * div + div / 2;
}
}
}
else if (image.channels() == 3)
{
for (int i = 0; i < nRows; ++i)
{
for (int j = 0; j < nCols; ++j)
{
image.at<Vec3b>(i, j)[0] = image.at<Vec3b>(i, j)[0] / div*div + div / 2;
image.at<Vec3b>(i, j)[1] = image.at<Vec3b>(i, j)[1] / div*div + div / 2;
image.at<Vec3b>(i, j)[2] = image.at<Vec3b>(i, j)[2] / div*div + div / 2;
}
}
}
}
// 3:使用迭代器進行圖像的遍歷
void colorReduceByIterator(Mat& image, int div = 64)
{
const int channels = image.channels();
switch (channels)
{
case 1:
{
MatIterator_<uchar>begin, end;
for (begin = image.begin<uchar>(), end = image.end<uchar>(); begin != end; ++begin)
{
*begin = *begin / div*div + div / 2;
}
break;
}
case 3:
{
MatIterator_<Vec3b> begin, end;
for (begin = image.begin<Vec3b>(), end = image.end<Vec3b>(); begin != end; ++begin)
{
(*begin)[0] = (*begin)[0] / div * div + div / 2;
(*begin)[1] = (*begin)[1] / div * div + div / 2;
(*begin)[2] = (*begin)[2] / div * div + div / 2;
}
break;
}
}
}
int main()
{
Mat image;
image = imread("E:\\dataset\\image.jpg");
if (!image.data)
return -1;
//cvtColor(image, image, CV_BGR2GRAY);
//colorReduceByAtMethod(image);
//colorReduceByPointer(image);
colorReduceByIterator(image);
namedWindow("after");
imshow("after", image);
cvWaitKey(-1);
destroyAllWindows();
return 0;
}