Opencv C ++ tres formas de acceder a los píxeles en la imagen

Descripción del procedimiento

// Descripción del programa: Tres métodos para que OpenCV C ++ acceda a los píxeles en las imágenes
// Referencia: Mao Xingyun "Introducción a la programación OpenCV3"
// Sistema operativo: Windows 10 64bit
// Lenguaje de desarrollo: C ++
// Versión IDE: Visual Studio 2019
/ / Versión OpenCV: 4.20

Cualquier algoritmo de procesamiento de imágenes comienza con la operación de cada píxel.
OpenCV proporciona tres algoritmos para acceder a cada píxel:
1. Acceso al puntero
2. Iterador
3. Cálculo dinámico de la dirección

La diferencia entre estos tres métodos es muy obvia en el modo de depuración, pero en el modo de lanzamiento, la diferencia no es obvia. Para mejorar la eficiencia del acceso, utilizamos la función colorReduce; para reducir el espacio de color para reducir el trabajo de color.

El método uno usa punteros para acceder a los píxeles

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

//-----------------------------------【全局函数声明部分】-----------------------------------
//          描述:全局函数声明
//-----------------------------------------------------------------------------------------------
void colorReduce(Mat& inputImage, Mat& outputImage, int div);



//--------------------------------------【main( )函数】---------------------------------------
//          描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main()
{
	//【1】创建原始图并显示
	Mat srcImage = imread("100.jpg");
	imshow("原始图像", srcImage);

	//【2】按原始图的参数规格来创建创建效果图
	Mat dstImage;
	dstImage.create(srcImage.rows, srcImage.cols, srcImage.type());//效果图的大小、类型与原图片相同 

	//【3】记录起始时间
	double time0 = static_cast<double>(getTickCount());  //记录开始时间

	//【4】调用颜色空间缩减函数
	colorReduce(srcImage, dstImage, 32);

	//【5】计算运行时间并输出
	time0 = ((double)getTickCount() - time0) / getTickFrequency();   //结束时间-开始时间,并化为秒单位
	cout << "\t此方法运行时间为: " << time0 << "秒" << endl;  //输出运行时间

	//【6】显示效果图
	imshow("效果图", dstImage);
	waitKey(0);
}


//---------------------------------【colorReduce( )函数】---------------------------------
//          描述:使用【指针访问:C操作符[ ]】方法版的颜色空间缩减函数
//----------------------------------------------------------------------------------------------
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
	//参数准备
	outputImage = inputImage.clone();  //拷贝实参到临时变量
	int rowNumber = outputImage.rows;  //行数
	int colNumber = outputImage.cols * outputImage.channels();  //列数 x 通道数=每一行元素的个数

	//双重循环,遍历所有的像素值
	for (int i = 0; i < rowNumber; i++)  //行循环
	{
		uchar* data = outputImage.ptr<uchar>(i);  //获取第i行的首地址
		for (int j = 0; j < colNumber; j++)   //列循环
		{
			// ---------【开始处理每个像素】-------------     
			data[j] = data[j] / div * div + div / 2;
			// ----------【处理结束】---------------------
		}  //行处理结束
	}
}

resultado de ejecución

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquíInserte la descripción de la imagen aquí

Método 2: use iteradores para acceder a los píxeles

//-------------------------------------【colorReduce( )函数】-----------------------------
//		描述:使用【迭代器】方法版的颜色空间缩减函数
//----------------------------------------------------------------------------------------------
void colorReduce(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;  
		// ------------------------【处理结束】----------------------------
	}  
}  

resultado de ejecución

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Método dos: utilice el cálculo dinámico de direcciones con at para acceder a los píxeles

//----------------------------------【colorReduce( )函数】-------------------------------
//          描述:使用【动态地址运算配合at】方法版本的颜色空间缩减函数
//----------------------------------------------------------------------------------------------
void colorReduce(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;  //红是通道
			// -------------------------【处理结束】----------------------------
		}  // 行处理结束     
	}  
}  

resultado de ejecución

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

para resumir

Comparando los tres métodos, el primero es el más rápido.

Supongo que te gusta

Origin blog.csdn.net/m0_51233386/article/details/114599460
Recomendado
Clasificación