本文主要实现了图像的负片算法,具体实现过程中,分别采用了四种遍历图像像素的方式,并对其遍历时间进行了对比。
四种访问方式分别如下:
【方式一类数组方式】
void Negative1(Mat image, Mat &result)
{
result.create(image.size(), image.type());
result.setTo(0);
int i, j;
int nl = image.rows;//行数
int nc = image.cols;//列数
for (int j = 0; j < nl; j++)
{
for (int i = 0; i < nc; i++)
{
result.at<Vec3b>(j, i)[0] = 255 - image.at<Vec3b>(j, i)[0];
result.at<Vec3b>(j, i)[1] = 255 - image.at<Vec3b>(j, i)[1];
result.at<Vec3b>(j, i)[2] = 255 - image.at<Vec3b>(j, i)[2];
}
}
}
【方式二迭代器方式】
void Negative2(Mat image, Mat &result)
{
result.create(image.size(), image.type());
result.setTo(0);
Mat_<Vec3b>::iterator it = image.begin<Vec3b>();
Mat_<Vec3b>::iterator itend = image.end<Vec3b>();
Mat_<Vec3b>::iterator itt = result.begin<Vec3b>();
for (; it != itend; ++it, ++itt)
{
(*itt)[0] = 255 - (*it)[0];
(*itt)[1] = 255 - (*it)[1];
(*itt)[2] = 255 - (*it)[2];
}
}
【方式三指针方式】
void Negative3(Mat image, Mat &result)
{
result.create(image.size(), image.type());
result.setTo(0);
int i;
int n = image.cols*image.rows*image.channels();//列数
uchar *src = image.ptr<uchar>(0);
uchar *dest = result.ptr<uchar>(0);
for (i = 0; i < n ; i++)
{
*dest = 255 - *src;
dest++, src++;
}
}
【方式四改进指针方式】
void Negative4(Mat image, Mat &result)
{
result.create(image.size(), image.type());
result.setTo(0);
int i;
int n = image.cols*image.rows;//列数
uchar *src = image.ptr<uchar>(0);
uchar *dest = result.ptr<uchar>(0);
for (i = 0; i < n; i++)
{
*dest = 255 - *src;
dest++, src++;
*dest = 255 - *src;
dest++, src++;
*dest = 255 - *src;
dest++, src++;
}
}
【测试代码】
int main()
{
Mat image = imread("1.jpg");
if (image.empty())
{
cout << "read file error!" << endl;
return -1;
}
Mat result1, result2, result3, result4;
double duration;
duration = static_cast<double>(getTickCount());
Negative1( image, result1);
duration = static_cast<double>(getTickCount())-duration;
duration /= getTickFrequency();
cout << "time consume is " << duration << " ms."<<endl;
duration = static_cast<double>(getTickCount());
Negative2(image, result2);
duration = static_cast<double>(getTickCount()) - duration;
duration /= getTickFrequency();
cout << "time consume is " << duration << " ms." << endl;
duration = static_cast<double>(getTickCount());
Negative3(image, result3);
duration = static_cast<double>(getTickCount()) - duration;
duration /= getTickFrequency();
cout << "time consume is " << duration << " ms." << endl;
duration = static_cast<double>(getTickCount());
Negative4(image, result4);
duration = static_cast<double>(getTickCount()) - duration;
duration /= getTickFrequency();
cout << "time consume is " << duration << " ms." << endl;
imshow("0", image);
imshow("1", result1);
imshow("2", result2);
imshow("3", result3);
imshow("4", result4);
waitKey(0);
system("pause");
return 0;
}
【运行时间效果对比】
由上图可知,通过指针方式遍历优于通过迭代器方式遍历,通过迭代器方式遍历优于通过数组器方式遍历。