#include"stdafx.h"
#include <opencv2/core/utility.hpp>
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
void colorReduce_point(Mat &, Mat &, int);
void colorReduce_iterator(Mat &, Mat &, int);
void colorReduce_dynamic(Mat &, Mat &, int div);
// 定义全局变量
int main() {
system("color 5E");
//读取图片
Mat srcImage = imread("E:\\pictures\\For_Project\\New_opencv\\Sceen\\yj.jpg");
namedWindow("【原始图像】", 1);
imshow("【原始图像】", srcImage);
//创建新的和原图片一样大小的空白图片
Mat new_Image1 = Mat::zeros(srcImage.size(), srcImage.type());
Mat new_Image2 = Mat::zeros(srcImage.size(), srcImage.type());
Mat new_Image3 = Mat::zeros(srcImage.size(), srcImage.type());
// Mat new_Image;
// new_Image.create(srcImage.size(),srcImage.type());
//记录起始时间,开始计时
double time0 = static_cast<double>(getTickCount());
//调用指针访问的方法执行颜色空间缩减函数
colorReduce_point(srcImage, new_Image1, 64);
//计算运行时间并输出
time0 = ((double)getTickCount() - time0) / getTickFrequency();
cout << "指针法该方法运行时间为:" << time0 << "秒" << endl;
//记录起始时间,开始计时
double time1 = static_cast<double>(getTickCount());
//调用指针访问的方法执行颜色空间缩减函数
colorReduce_iterator(srcImage, new_Image2, 64);
//计算运行时间并输出
time1 = ((double)getTickCount() - time1) / getTickFrequency();
cout << "迭代器该方法运行时间为:" << time1 << "秒" << endl;
//显示效果图
imshow("指针法效果图", new_Image1);
imshow("迭代器法效果图", new_Image2);
//记录起始时间,开始计时
double time2 = static_cast<double>(getTickCount());
//调用指针访问的方法执行颜色空间缩减函数
colorReduce_dynamic(srcImage, new_Image3, 64);
//计算运行时间并输出
time2 = ((double)getTickCount() - time2) / getTickFrequency();
cout << "迭代器该方法运行时间为:" << time2 << "秒" << endl;
//显示效果图
imshow("指针法效果图", new_Image1);
imshow("迭代器法效果图", new_Image2);
imshow("动态访问法效果图", new_Image3);
//等待键盘按键‘q’退出
while (char(waitKey(1)) != 'q') {}
return 0;
}
//指针访问像素
void colorReduce_point(Mat &inputImage,Mat &outputImage,int div) {
//参数准备拷贝
//复制原始图像到临时变量
outputImage = inputImage.clone();
//分别得到行数和列数
int rowsNumber = outputImage.rows;
int colsNumber = outputImage.cols*outputImage.channels();
//双重循环,遍历所有的像素值
for (int i = 0;i < rowsNumber;i++) {
//获取第i行的首地址
uchar*data = outputImage.ptr<uchar>(i);
for (int j = 0;j < colsNumber;j++) {
//开始执行像素操作
data[j] = data[j] / div*div + div / 2;
}
}
}
//迭代器操作像素
void colorReduce_iterator(Mat &inputImage, Mat &outputImage, int div) {
//参数准备拷贝
//复制原始图像到临时变量
outputImage = inputImage.clone();
//获取迭代器
//获取迭代器初始位置
Mat_<Vec3b>::iterator it = outputImage.begin<Vec3b>();
//获取迭代器终止位置
Mat_<Vec3b>::iterator itend = outputImage.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;
}
}
void colorReduce_dynamic(Mat &inputImage, Mat &outputImage, int div) {
//参数准备拷贝
//复制原始图像到临时变量
outputImage = inputImage.clone();
//得到行数和列数
int rowsNumber = outputImage.rows;
int colsNumber = outputImage.cols;
for (int i = 0;i < rowsNumber;i++) {
for (int j = 0;j < colsNumber;j++) {
//操作每一个像素值
//蓝色通道
outputImage.at<Vec3b>(i, j)[0] = outputImage.at<Vec3b>(i, j)[0] / div*div + div / 2;
//绿色通道
outputImage.at<Vec3b>(i, j)[1] = outputImage.at<Vec3b>(i, j)[1] / div*div + div / 2;
//红色通道
outputImage.at<Vec3b>(i, j)[2] = outputImage.at<Vec3b>(i, j)[2] / div*div + div / 2;
}
}
}
opencv学习三种常用方法访问操作图像像素
最新推荐文章于 2023-02-16 08:43:31 发布