Escala de color automática de procesamiento de imágenes opencv & c ++

Escala de color automática

El primer paso es contar los histogramas de cada canal (rojo / verde / azul) respectivamente.

El segundo paso es calcular los límites superior e inferior de cada canal de acuerdo con los parámetros dados. ¿Qué significa? Por ejemplo, para el canal azul, acumulamos el histograma estadístico desde el nivel 0 hacia arriba. Cuando el valor acumulado es mayor que el número de píxeles en LowCut , el valor del nivel en este momento se cuenta como BMin. Luego acumule el histograma desde el nivel de gradación 255 hacia abajo. Si el valor acumulado es mayor que todos los píxeles de HighCut , el valor de gradación en este momento se cuenta como BMax.

El tercer paso es construir una tabla de mapeo de acuerdo con el MinBlue / MaxBlue que acabamos de calcular. La regla de la tabla de mapeo es que para un valor menor que MinBlue, el implícito es 0 (de hecho, esta oración no es correcta, cuánto es el implícito Está relacionado con el color establecido por la sombra en el cuadro de diálogo de la opción de corrección automática de color. Por defecto, es negro, y los componentes RGB correspondientes son todos 0, por lo que implicaremos 0 aquí. Si está interesado, también puede especificar otros Parámetro), para un valor mayor que MaxBlue, el implícito es 255 (de manera similar, este valor está relacionado con la configuración de color del resaltado), para un valor entre MinBlue y MaxBlue, se realiza lineal implícito y el predeterminado es implícito Está entre 0 y 255 (por supuesto, en realidad está relacionado con nuestra configuración de tono oscuro y resaltado, y aquí en realidad no hay un implícito lineal, hay una corrección Gamma, por simplicidad, no hay un gran problema con el efecto de reemplazo lineal).

El último paso es inferir los datos de imagen de cada canal.

// AutoLevel.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<iostream>
#include<vector>
#include <algorithm>
using namespace cv;

void AutoLevelsAdjust(cv::Mat& src, cv::Mat& dst)
{
    
    
	CV_Assert(!src.empty() && src.channels() == 3);

	//统计灰度直方图
	int BHist[256] = {
    
     0 };	//B分离
	int GHist[256] = {
    
     0 };	//G分量
	int RHist[256] = {
    
     0 };	//R分量
	cv::MatIterator_<Vec3b> its, ends;
	for (its = src.begin<Vec3b>(), ends = src.end<Vec3b>(); its != ends; its++)
	{
    
    
		BHist[(*its)[0]]++;
		GHist[(*its)[1]]++;
		RHist[(*its)[2]]++;
	}

	//设置LowCut和HighCut
	float LowCut = 0.5;
	float HighCut = 0.5;

	//根据LowCut和HighCut查找每个通道最大值最小值
	int BMax = 0, BMin = 0;
	int GMax = 0, GMin = 0;
	int RMax = 0, RMin = 0;

	int TotalPixels = src.cols * src.rows;
	float LowTh = LowCut * 0.01 * TotalPixels;
	float HighTh = HighCut * 0.01 * TotalPixels;

	//B通道查找最小最大值
	int sumTempB = 0;
	for (int i = 0; i < 256; i++)
	{
    
    
		sumTempB += BHist[i];
		if (sumTempB >= LowTh)
		{
    
    
			BMin = i;
			break;
		}
	}
	sumTempB = 0;
	for (int i = 255; i >= 0; i--)
	{
    
    
		sumTempB += BHist[i];
		if (sumTempB >= HighTh)
		{
    
    
			BMax = i;
			break;
		}
	}

	//G通道查找最小最大值
	int sumTempG = 0;
	for (int i = 0; i < 256; i++)
	{
    
    
		sumTempG += GHist[i];
		if (sumTempG >= LowTh)
		{
    
    
			GMin = i;
			break;
		}
	}
	sumTempG = 0;
	for (int i = 255; i >= 0; i--)
	{
    
    
		sumTempG += GHist[i];
		if (sumTempG >= HighTh)
		{
    
    
			GMax = i;
			break;
		}
	}

	//R通道查找最小最大值
	int sumTempR = 0;
	for (int i = 0; i < 256; i++)
	{
    
    
		sumTempR += RHist[i];
		if (sumTempR >= LowTh)
		{
    
    
			RMin = i;
			break;
		}
	}
	sumTempR = 0;
	for (int i = 255; i >= 0; i--)
	{
    
    
		sumTempR += RHist[i];
		if (sumTempR >= HighTh)
		{
    
    
			RMax = i;
			break;
		}
	}

	//对每个通道建立分段线性查找表
	//B分量查找表
	int BTable[256] = {
    
     0 };
	for (int i = 0; i < 256; i++)
	{
    
    
		if (i <= BMin)
			BTable[i] = 0;
		else if (i > BMin && i < BMax)
			BTable[i] = cvRound((float)(i - BMin) / (BMax - BMin) * 255);
		else
			BTable[i] = 255;
	}

	//G分量查找表
	int GTable[256] = {
    
     0 };
	for (int i = 0; i < 256; i++)
	{
    
    
		if (i <= GMin)
			GTable[i] = 0;
		else if (i > GMin && i < GMax)
			GTable[i] = cvRound((float)(i - GMin) / (GMax - GMin) * 255);
		else
			GTable[i] = 255;
	}

	//R分量查找表
	int RTable[256] = {
    
     0 };
	for (int i = 0; i < 256; i++)
	{
    
    
		if (i <= RMin)
			RTable[i] = 0;
		else if (i > RMin && i < RMax)
			RTable[i] = cvRound((float)(i - RMin) / (RMax - RMin) * 255);
		else
			RTable[i] = 255;
	}

	//对每个通道用相应的查找表进行分段线性拉伸
	cv::Mat dst_ = src.clone();
	cv::MatIterator_<Vec3b> itd, endd;
	for (itd = dst_.begin<Vec3b>(), endd = dst_.end<Vec3b>(); itd != endd; itd++)
	{
    
    
		(*itd)[0] = BTable[(*itd)[0]];
		(*itd)[1] = GTable[(*itd)[1]];
		(*itd)[2] = RTable[(*itd)[2]];
	}
	dst = dst_;
}

int main()
{
    
    
	Mat image = imread("E:\\picture\\wutian.jpg");
	Mat dst = Mat::zeros(image.rows, image.cols, CV_8UC1);
	AutoLevelsAdjust(image, dst);
	imshow("src", image);
	imshow("dst", dst);
	while (char(waitKey(1)) != 'q') {
    
    }
}


Inserte la descripción de la imagen aquí

La gradación de color automática se utiliza para el desempañado, que sigue siendo el más estable. Aunque existen muchos otros métodos de mejora, como el desempañado del canal oscuro, el desempañado de contraste optimizado y el desempañado basado en líneas de color, estos algoritmos aún no son muy estables. Cuando el conocimiento previo no es válido, la distorsión del procesamiento es más grave. Pero la escala de colores automática es relativamente estable.

Supongo que te gusta

Origin blog.csdn.net/qq_36587495/article/details/108582564
Recomendado
Clasificación