opencv學習筆記1::訪問圖像中像素的三類方法(用指針,迭代器,動態地址)代碼及用時檢測

本文參考《Opencv3 入門》 作者毛星雲


//---------------------------------【頭文件、命名空間包含部分】----------------------------

// 描述:包含程序所使用的頭文件和命名空間
//-----------------------------------------------------------------------------------------


#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;




//---------------------------------【用指針訪問像素colorReduce1()函數部分】----------------------------
// 描述:用指針訪問像素
//-----------------------------------------------------------------------------------------


void colorReduce1(Mat& inputImage, Mat& outputImage, int div)
{
outputImage = inputImage.clone();//複製實參到臨時變量
int rowNumber = outputImage.rows;//行數
int colNumber = outputImage.cols * outputImage.channels();   //每一行元素的個數
for (int i = 0; i < rowNumber; i++)
{
uchar* data = outputImage.ptr<uchar>(i);
for (int j = 0; j < colNumber; j++)
{
data[j] = data[j] / div*div + div / 2;
}
}
}


//---------------------------------【用迭代器操作像素colorReduce2()函數部分】----------------------------
// 描述:用迭代器操作像素
//-----------------------------------------------------------------------------------------


void colorReduce2(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;
}
}


//---------------------------------【用動態地址計算來操作像素colorReduce3()函數部分】----------------------------
// 描述:用動態地址計算來操作像素
//-----------------------------------------------------------------------------------------


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 < colNumber; 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;
}
}
}




//---------------------------------【主函數main()部分】----------------------------
// 描述:main()主函數部分
//-----------------------------------------------------------------------------------------
int main()
{
for (int i = 1; i <= 3; i++)
{
Mat inputImage = imread("E:/3.jpg");
Mat outputImage;
imshow("源圖", inputImage);


if (i == 1)
{
double time_1= static_cast<double>(getTickCount());
colorReduce1(inputImage, outputImage, 50);
time_1 = ((double)getTickCount() - time_1) / getTickFrequency();
imshow("指針訪問像素", outputImage);
cout << "用指針訪問像素用時" << time_1 << "secends" << endl;
waitKey(5000);
}
if (i == 2)
{
double time_2 = static_cast<double>(getTickCount());
colorReduce2(inputImage, outputImage, 50);
time_2 = ((double)getTickCount() - time_2) / getTickFrequency();
imshow("用迭代器操作元素", outputImage);
waitKey(5000);
cout << "用迭代器操作元素用時" << time_2 << "secends" << endl;
}
if (i == 3)
{
double  time_3 = static_cast<double>(getTickCount());
colorReduce3(inputImage, outputImage, 50);
time_3 = ((double)cvGetTickCount() - time_3) / getTickFrequency();
imshow("使用動態地址操作元素", outputImage);
cout << "使用動態地址操作元素用時" << time_3 << "secend" << endl;
waitKey(0);
}
}
system("pause");

}


調試結果:








可以清楚的看書,用指針訪問像素的方法用時最小。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章