基于OpenCV的彩色图像色彩增强代码(C++代码)

本文代码来自于下面这篇博文:
https://blog.csdn.net/matt45m/article/details/104673585/

原文中只给出了函数,没有给出完整的可运行的代码。也没有说明第三个参数filter的意义和该取什么值。

实际跑了下,原文提供的函数一点问题没有,并且实测把filter的值置为1,可实现博文中的运行效果。

完整代码如下:
代码中用到的图像如下:
请添加图片描述

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

//博主微信/QQ 2487872782
//有问题可以联系博主交流
//有图像处理开发需求也请联系博主
//图像处理技术交流QQ群 271891601

void colorEnhancement(cv::Mat &src, cv::Mat &dst, int filter)
{
    
    

	cv::Mat orig_img = src.clone();
	cv::Mat simg;

	if (orig_img.channels() != 1)
	{
    
    
		cvtColor(orig_img, simg, CV_BGR2GRAY);
	}
	else
	{
    
    
		return;
	}

	long int N = simg.rows*simg.cols;

	int histo_b[256];
	int histo_g[256];
	int histo_r[256];

	for (int i = 0; i<256; i++)
	{
    
    
		histo_b[i] = 0;
		histo_g[i] = 0;
		histo_r[i] = 0;
	}
	cv::Vec3b intensity;

	for (int i = 0; i<simg.rows; i++)
	{
    
    
		for (int j = 0; j<simg.cols; j++)
		{
    
    
			intensity = orig_img.at<cv::Vec3b>(i, j);

			histo_b[intensity.val[0]] = histo_b[intensity.val[0]] + 1;
			histo_g[intensity.val[1]] = histo_g[intensity.val[1]] + 1;
			histo_r[intensity.val[2]] = histo_r[intensity.val[2]] + 1;
		}
	}

	for (int i = 1; i<256; i++)
	{
    
    
		histo_b[i] = histo_b[i] + filter * histo_b[i - 1];
		histo_g[i] = histo_g[i] + filter * histo_g[i - 1];
		histo_r[i] = histo_r[i] + filter * histo_r[i - 1];
	}

	int vmin_b = 0;
	int vmin_g = 0;
	int vmin_r = 0;
	int s1 = 3;
	int s2 = 3;

	while (histo_b[vmin_b + 1] <= N*s1 / 100)
	{
    
    
		vmin_b = vmin_b + 1;
	}
	while (histo_g[vmin_g + 1] <= N*s1 / 100)
	{
    
    
		vmin_g = vmin_g + 1;
	}
	while (histo_r[vmin_r + 1] <= N*s1 / 100)
	{
    
    
		vmin_r = vmin_r + 1;
	}

	int vmax_b = 255 - 1;
	int vmax_g = 255 - 1;
	int vmax_r = 255 - 1;

	while (histo_b[vmax_b - 1]>(N - ((N / 100)*s2)))
	{
    
    
		vmax_b = vmax_b - 1;
	}
	if (vmax_b < 255 - 1)
	{
      
      
		vmax_b = vmax_b + 1;
	}
	while (histo_g[vmax_g - 1]>(N - ((N / 100)*s2)))
	{
    
    
		vmax_g = vmax_g - 1;
	}
	if (vmax_g < 255 - 1)
	{
      
      
		vmax_g = vmax_g + 1;
	}
	while (histo_r[vmax_r - 1]>(N - ((N / 100)*s2)))
	{
    
    
		vmax_r = vmax_r - 1;
	}
	if (vmax_r < 255 - 1)
	{
    
    
		vmax_r = vmax_r + 1;
	}

	for (int i = 0; i<simg.rows; i++)
	{
    
    
		for (int j = 0; j<simg.cols; j++)
		{
    
    

			intensity = orig_img.at<cv::Vec3b>(i, j);

			if (intensity.val[0]<vmin_b)
			{
    
    
				intensity.val[0] = vmin_b;
			}
			if (intensity.val[0]>vmax_b)
			{
    
    
				intensity.val[0] = vmax_b;
			}


			if (intensity.val[1]<vmin_g)
			{
    
    
				intensity.val[1] = vmin_g;
			}
			if (intensity.val[1]>vmax_g)
			{
    
    
				intensity.val[1] = vmax_g;
			}

			if (intensity.val[2]<vmin_r)
			{
    
    
				intensity.val[2] = vmin_r;
			}
			if (intensity.val[2]>vmax_r)
			{
    
    
				intensity.val[2] = vmax_r;
			}

			orig_img.at<cv::Vec3b>(i, j) = intensity;
		}
	}

	for (int i = 0; i<simg.rows; i++)
	{
    
    
		for (int j = 0; j<simg.cols; j++)
		{
    
    

			intensity = orig_img.at<cv::Vec3b>(i, j);
			intensity.val[0] = (intensity.val[0] - vmin_b) * 255 / (vmax_b - vmin_b);
			intensity.val[1] = (intensity.val[1] - vmin_g) * 255 / (vmax_g - vmin_g);
			intensity.val[2] = (intensity.val[2] - vmin_r) * 255 / (vmax_r - vmin_r);
			orig_img.at<cv::Vec3b>(i, j) = intensity;
		}
	}


	cv::Mat blurred;
	double sigma = 1;
	double threshold = 50;
	double amount = 1;
	GaussianBlur(orig_img, blurred, cv::Size(), sigma, sigma);
	cv::Mat lowContrastMask = abs(orig_img - blurred) < threshold;
	cv::Mat sharpened = orig_img*(1 + amount) + blurred*(-amount);
	orig_img.copyTo(sharpened, lowContrastMask);
	dst = sharpened.clone();
}



int main()
{
    
    
	Mat src_image = imread("F:/material/images/2022/2022-06/gufeng1.jpg");
	if (src_image.empty())
	{
    
    
		std::cout << "Error: Could not load image" << std::endl;
		return 0;
	}

	imshow("Source Image", src_image);

	Mat dst_image;
	int filter = 1;
	colorEnhancement(src_image, dst_image, filter);


	imshow("dst_image", dst_image);

	waitKey();
	return(0);
}

运行结果如下:
在这里插入图片描述
至于原理,以后有需要的时候再探究吧!

猜你喜欢

转载自blog.csdn.net/wenhao_ir/article/details/125664777