OpenCV 访问图像中的像素|颜色空间缩减
在OpenCV中,提供了三种访问每个像素的方法。
- 方法一指针访问:C操作符[];
- 方法二迭代器iterator;
- 方法三动态地址计算。
#include
#include
#include
using namespace cv;
using namespace std;
/*指针访问:C 操作符[]*/
void colorReduce1(Mat& inputImage, Mat& outputImage, int div)
{
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(i); // 获取 i 行首地址
// 列循环
for (int j = 0; j < colNumber; j++) {
data[j] = (data[j] / div) * div + div / 2;
// 也可以
//*data++ = (*data / div) * div + div / 2;
}
}
}
/*用迭代器操作像素*/
void colorReduce2(Mat& inputImage, Mat& outputImage, int div)
{
outputImage = inputImage.clone();
// 获取迭代器
Mat_::iterator it = outputImage.begin(); //初始位置迭代器
Mat_::iterator itend = outputImage.end(); // 终止位置迭代器
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;
// 处理结束
}
}
/*动态地址计算*/
void colorReduce3(Mat& inputImage, Mat& outputImage, int div)
{
outputImage = inputImage.clone(); // 复制实参到临时变量
int rowNumber = outputImage.rows;
int colNumber = outputImage.cols;
for (int i = 0; i < rowNumber; i++) {
for (int j = 0; j < rowNumber; j++) {
// 处理开始
// 蓝色通道
outputImage.at(i, j)[0] = (outputImage.at(i, j)[0] / div) * div + div / 2;
// 绿色通道
outputImage.at(i, j)[1] = (outputImage.at(i, j)[1] / div) * div + div / 2;
// 红色通道
outputImage.at(i, j)[2] = (outputImage.at(i, j)[2] / div) * div + div / 2;
// 处理结束
}
}
}
int main(int argc, char ** argv)
{
Mat srcImage = imread(".//image5.1//1.jpg");
imshow("原图", srcImage);
Mat dstImage1;
Mat dstImage2;
Mat dstImage3;
dstImage1.create(srcImage.rows, srcImage.cols, srcImage.type()); // 效果图的大小与原始图的大小类型相同
dstImage2.create(srcImage.rows, srcImage.cols, srcImage.type()); // 效果图的大小与原始图的大小类型相同
dstImage3.create(srcImage.rows, srcImage.cols, srcImage.type()); // 效果图的大小与原始图的大小类型相同
// 记录起始时间
double time0 = static_cast(getTickCount());
// 调用缩减函数1
colorReduce1(srcImage, dstImage1, 32); // 256 / 32 = 8
time0 = ((double)getTickCount() - time0) / getTickFrequency();
cout << "指针访问:C操作符[]运行时间为:" << time0 << "秒" << endl;
imshow("效果图1", dstImage1);
time0 = static_cast(getTickCount());
// 调用缩减函数2
colorReduce2(srcImage, dstImage2, 32); // 256 / 32 = 8
time0 = ((double)getTickCount() - time0) / getTickFrequency();
cout << "迭代器操作,运行时间为:" << time0 << "秒" << endl;
imshow("效果图2", dstImage2);
time0 = static_cast(getTickCount());
// 调用缩减函数2
colorReduce3(srcImage, dstImage3, 32); // 256 / 32 = 8
time0 = ((double)getTickCount() - time0) / getTickFrequency();
cout << "动态地址计算,运行时间为:" << time0 << "秒" << endl;
imshow("效果图3", dstImage3);
waitKey(0);
return(0);
}
运行 3 次时间对比:
指针访问:C操作符[]运行时间为:0.002704秒
迭代器操作,运行时间为:0.0986663秒
动态地址计算,运行时间为:0.0809037秒
指针访问:C操作符[]运行时间为:0.0028266秒
迭代器操作,运行时间为:0.0972075秒
动态地址计算,运行时间为:0.0750282秒
指针访问:C操作符[]运行时间为:0.0027457秒
迭代器操作,运行时间为:0.0951924秒
动态地址计算,运行时间为:0.0748235秒
图像输出:
参考:
《OpenCV3 编程入门》 毛星云 P111