OpenCV计算机视觉编程记录(06)---------减色方法进行测试,比较其运行时间。
程序员文章站
2024-03-25 11:07:52
...
对以下减色方法进行测试,比较其运行时间。
方法1:使用整数除法
方法2:使用取模运算符方法
方法3:使用位运算符方法
方法4:使用整数除法和迭代器方法
方法5:使用整数除法和at方法
要求:
1、为每一种方法封装1个函数
2、不要求输出图像,但要输出每种方法的处理时间
源码:
#include<opencv2\highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;
void colorReduce(cv::Mat image);
void getMo(Mat image);
void weiMeth(Mat image,int n=6){
uchar div=pow(2,n);
uchar div2=div>>1;
uchar mask = uchar(0xFF) << n;
int nr=image.rows;
int nc = image.cols * image.channels();
for (int j = 0; j < nr; j++) { // 遍历每一行
// 取得行j的地址
uchar* data = image.ptr<uchar>(j);
// 遍历当前行每一个元素
for (int i = 0; i < nc; i++) {
// 处理每个元素---------------------
*data &= mask; // 掩码,将后n位设为0
*data++ += div2;
}
}
}
void colorReduce2(cv::Mat image, int div = 64) {
// 在初始位置获得迭代器
cv::MatIterator_<cv::Vec3b> it =
image.begin<cv::Vec3b>();
// 获得结束位置
cv::MatIterator_<cv::Vec3b> itend =
image.end<cv::Vec3b>();
// 遍历所有像素
for (; it != itend; ++it) {
// 处理每个像素-------------------------
(*it)[0] = cv::saturate_cast<uchar>(
(*it)[0] / div * div + div / 2);
(*it)[1] = cv::saturate_cast<uchar>(
(*it)[1] / div * div + div / 2);
(*it)[2] = cv::saturate_cast<uchar>(
(*it)[2] / div * div + div / 2);
// 像素处理结束-------------------------
}
}
void colorReduce3(Mat image,int div=64){
int nr=image.rows;
int nc=image.cols;
for(int j=0;j<nr;j++){
for(int i=0;i<nc;i++){
image.at<Vec3b>(j,i)[0]=saturate_cast<uchar>(
image.at<Vec3b>(j,i)[0]/div*div+div/2);
image.at<Vec3b>(j,i)[1]=saturate_cast<uchar>(
image.at<Vec3b>(j,i)[1]/div*div+div/2);
image.at<Vec3b>(j,i)[2]=saturate_cast<uchar>(
image.at<Vec3b>(j,i)[2]/div*div+div/2);
}
}
}
int main()
{
Mat image=imread("原图.png");
//imshow("原图",image);
if(image.empty())
{
cout<<"empty image";
getchar();
return 0;
}
const int64 start = getTickCount();
colorReduce(image);
double duration = (getTickCount()-start) / getTickFrequency();
cout<<"1.整除法时间为:"<<duration<<"s"<<endl;
//imshow("整除法",image);
//const int64 start = getTickCount();
getMo(image);
duration = (getTickCount()-start) / getTickFrequency();
cout<<"2.取模运算法时间为:"<<duration<<"s"<<endl;
//imshow("取模运算符",image);
//const int64 start = getTickCount();
weiMeth(image);
duration = (getTickCount()-start) / getTickFrequency();
cout<<"3.位运算时间为:"<<duration<<"s"<<endl;
//imshow("位运算符",image);
//const int64 start = getTickCount();
colorReduce2(image);
duration = (getTickCount()-start) / getTickFrequency();
cout<<"4.迭代器时间为:"<<duration<<"s"<<endl;
//imshow("迭代器",image);
//const int64 start = getTickCount();
colorReduce3(image);
duration = (getTickCount()-start) / getTickFrequency();
cout<<"5.at时间为:"<<duration<<"s"<<endl;
//imshow("at",image);
waitKey();
return 0;
}
void colorReduce(cv::Mat image) {
int div = 64;
int nr = image.rows; // 行数
// 每行的元素数量(注意不是像素数量)
int nc = image.cols * image.channels();
for (int j = 0; j < nr; j++) { // 遍历每一行
// 取得行j的地址
uchar* data = image.ptr<uchar>(j);
// 遍历当前行每一个元素
for (int i = 0; i < nc; i++) {
// 处理每个元素---------------------
data[i] = cv::saturate_cast<uchar>(
data[i] / div * div + div / 2);
// 元素处理结束---------------------
} // 一行结束
}
}
void getMo(Mat image){
int div = 64;
int nr = image.rows; // 行数
// 每行的元素数量(注意不是像素数量)
int nc = image.cols * image.channels();
for (int j = 0; j < nr; j++) { // 遍历每一行
// 取得行j的地址
uchar* data = image.ptr<uchar>(j);
// 遍历当前行每一个元素
for (int i = 0; i < nc; i++) {
// 处理每个元素---------------------
data[i] = cv::saturate_cast<uchar>(data[i] - data[i] % div + div / 2);
}
}
}