opencv遍历图像像素方法总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/love_image_xie/article/details/87465916
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/core/core.hpp>
#include<cmath>
#include<iostream>
#include<vector>
using namespace std;
using namespace cv;

Mat inverse1(Mat& src)
{
	Mat result1=src.clone();
	int row = src.rows;
	int col = src.cols;
	//分别对各通道处理
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			result1.at<Vec3b>(i, j)[0] = 255 - src.at<Vec3b>(i, j)[0];
			result1.at<Vec3b>(i, j)[1] = 255 - src.at<Vec3b>(i, j)[1];
			result1.at<Vec3b>(i, j)[2] = 255 - src.at<Vec3b>(i, j)[2];
		}
	}
	return result1;
}

Mat inverse2(Mat& src)
{
	Mat result2 = src.clone();
	int row = src.rows;
	//图像行实际的宽度
	int step = src.step;
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < step; j++)
		{
			result2.at<uchar>(i, j) = 255 - src.at<uchar>(i,j);
		}
	}
	return result2;
}

Mat inverse3(Mat& src)
{
	Mat result3 = src.clone();
	int row = src.rows;
	//3通道转化为单通道
	int nStep = src.cols*src.channels();
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < nStep; j++)
		{
			const uchar* pSrc = src.ptr<uchar>(i);
			uchar* pDst = result3.ptr<uchar>(i);
			pDst[j] = saturate_cast<uchar>(255 - pSrc[j]);
		}
	}
	return result3;
}

Mat inverse4(Mat& src)
{
	Mat result4 = src.clone();
	//初始化源图像迭代器
	Mat_<Vec3b>::iterator srcStart = src.begin<Vec3b>();
	Mat_<Vec3b>::iterator srcEnd = src.end<Vec3b>();
	//初始化输出图像迭代器
	Mat_<Vec3b>::iterator dstStart = result4.begin<Vec3b>();
	Mat_<Vec3b>::iterator dstEnd = result4.end<Vec3b>();
	while (srcStart != srcEnd)
	{
		(*dstStart)[0] = 255 - (*srcStart)[0];
		(*dstStart)[1] = 255 - (*srcStart)[1];
		(*dstStart)[2] = 255 - (*srcStart)[2];
		srcStart++;
		dstStart++;
	}
	return result4;
}

Mat inverse5(Mat& src)
{
	int row = src.rows;
	int col = src.cols;
	Mat result5 = src.clone();
	//判断是否连续
	if (src.isContinuous())
	{
		row = 1;
		col = col*row*src.channels();
	}
	for (int i = 0; i < row; i++)
	{
		const uchar* pSrc = src.ptr<uchar>(i);
		uchar* pDst = result5.ptr<uchar>(i);
		for (int j = 0; j < col; j++)
		{
			*pDst++ = 255 - *pSrc++;
		}
	}
	return result5;
}

Mat inverse6(Mat& src)
{
	int row = src.rows;
	int col = src.cols;
	Mat result6 = src.clone();
	//建立LUT
	uchar LutTable[256];
	for (int i = 0; i < 256; i++)
		LutTable[i] = 255 - i;
	Mat lookUpTable(1,256,CV_8U);
	uchar* pData = lookUpTable.data;
	//建立映射表
	for (int i = 0; i < 256; i++)
		pData[i] = LutTable[i];
	LUT(src, lookUpTable, result6);
	return result6;
}
int main()
{
	Mat src;
	src = imread("E:\\研究生\\学习材料\\学习书籍\\OpenCV图像处理编程实例-源码-20160801\\《OpenCV图像处理编程实例-源码-20160801\\images\\flower4.jpg");
	if (src.empty())
		return -1;
	imshow("src",src);
	Mat result1, result2, result3;
	//测试方法1
	double tTime;
	tTime = (double)getTickCount();
	const int nTimes = 100;
	for (int i = 0; i < nTimes; i++)
	{
		result1 = inverse1(src);
	}
	tTime = 1000 * ((double)getTickCount() - tTime) / getTickFrequency();
	tTime /= nTimes;
	cout << "at方法遍历像素-1: " << tTime << endl;

	tTime = (double)getTickCount();
	for (int i = 0; i < nTimes; i++)
	{
		result1 = inverse2(src);
	}
	tTime = 1000 * ((double)getTickCount() - tTime) / getTickFrequency();
	tTime /= nTimes;
	cout << "at方法-2: " << tTime << endl;

	tTime = (double)getTickCount();
	for (int i = 0; i < nTimes; i++)
	{
		result1 = inverse3(src);
	}
	tTime = 1000 * ((double)getTickCount() - tTime) / getTickFrequency();
	tTime /= nTimes;
	cout << "ptr指针方法:" << tTime << endl;

	tTime = (double)getTickCount();
	for (int i = 0; i < nTimes; i++)
	{
		result1 = inverse4(src);
	}
	tTime = 1000 * ((double)getTickCount() - tTime) / getTickFrequency();
	tTime /= nTimes;
	cout << "迭代器方法: " << tTime << endl;

	tTime = (double)getTickCount();
	for (int i = 0; i < nTimes; i++)
	{
		result1 = inverse5(src);
	}
	tTime = 1000 * ((double)getTickCount() - tTime) / getTickFrequency();
	tTime /= nTimes;
	cout << "改进的指针方法: " << tTime << endl;

	tTime = (double)getTickCount();
	for (int i = 0; i < nTimes; i++)
	{
		result1 = inverse6(src);
	}
	tTime = 1000 * ((double)getTickCount() - tTime) / getTickFrequency();
	tTime /= nTimes;
	cout << "LUT查表方法: " << tTime << endl;
	waitKey(0);
}


at方法遍历像素-1: 118.048
at方法-2: 88.4501
ptr指针方法:46.0381
迭代器方法: 155.983
改进的指针方法: 0.0849588
LUT查表方法: 1.78582

猜你喜欢

转载自blog.csdn.net/love_image_xie/article/details/87465916