OpenCV 对比度增强

图像增强的一种重要方法是对比度增强,常见的有以下几种方法:

直方图均衡,局部自适应对比度增强(ACE adaptiveContrastEnhancement),自适应直方图均衡(CLAHE),自动对比度。

1. 直方图均衡

        cv::equalizeHist(src, dst);

2. 自适应直方图均衡(CLAHE)参考

        cv::Mat clahe_img = srcGray.clone();
	cv::Mat clahe_dst;
	cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE();
	clahe->setClipLimit(8.);    // (int)(4.*(8*8)/256)
	clahe->setTilesGridSize(Size(32, 32)); // 将图像分为8*8块
	clahe->apply(clahe_img, clahe_dst);

3. 局部自适应对比度增强(ACE)参考

void adaptContrastEnhancement()
{
	cv::Mat srcMat = cv::imread("1.JPG");
	cv::Mat srcGray;
	cv::cvtColor(aConMat, srcGray, cv::COLOR_BGR2GRAY);

	const int WINSIZE = 15;
	const int MAXCG = 10;

	Mat localMeansMatrix(srcGray.rows, srcGray.cols, CV_32FC1);
	Mat localVarianceMatrix(srcGray.rows, srcGray.cols, CV_32FC1);

	if (!getVarianceMean(srcGray, localMeansMatrix, localVarianceMatrix, WINSIZE))   //对Y通道进行增强;
	{
		cerr << "计算图像均值与标准差过程中发生错误";
		return ;
	}

	Mat temp = srcGray.clone();

	Scalar  mean;
	Scalar  dev;
	meanStdDev(temp, mean, dev);

	float meansGlobal = mean.val[0];
	Mat dstMat(srcGray.rows, srcGray.cols, CV_8UC1);

	for (int i = 0; i < srcGray.rows; i++)            //遍历,对每个点进行自适应调节
	{
		for (int j = 0; j < srcGray.cols; j++)
		{
			if (localVarianceMatrix.at<float>(i, j) >= 0.01)
			{
				float cg = 0.3*meansGlobal / localVarianceMatrix.at<float>(i, j);
				float cgs = cg > MAXCG ? MAXCG : cg;
				cgs = cgs < 1 ? 1 : cgs;

				int e = localMeansMatrix.at<float>(i, j) + cgs * (temp.at<uchar>(i, j) - localMeansMatrix.at<float>(i, j));
				if (e > 255) { e = 255; }
				else if (e < 0) { e = 0; }
				dstMat.at<uchar>(i, j) = e;
			}
			else
			{
				dstMat.at<uchar>(i, j) = temp.at<uchar>(i, j);
			}
		}

	}
}

bool getVarianceMean(Mat &scr, Mat &meansDst, Mat &varianceDst, int winSize)
{
	if (!scr.data)  //判断图像是否被正确读取;
	{
		cerr << "获取方差与均值的函数读入图片有误";
		return false;
	}

	if (winSize % 2 == 0)
	{
		cerr << "计算局部均值与标准差的窗口大小应该为单数";
		return false;
	}

	Mat copyBorder_yChannels;                        //扩充图像边界;
	int copyBorderSize = (winSize - 1) / 2;
	copyMakeBorder(scr, copyBorder_yChannels, copyBorderSize, copyBorderSize, copyBorderSize, copyBorderSize, BORDER_REFLECT);

	for (int i = (winSize - 1) / 2; i < copyBorder_yChannels.rows - (winSize - 1) / 2; i++)
	{
		for (int j = (winSize - 1) / 2; j < copyBorder_yChannels.cols - (winSize - 1) / 2; j++)
		{

			Mat temp = copyBorder_yChannels(Rect(j - (winSize - 1) / 2, i - (winSize - 1) / 2, winSize, winSize));   //截取扩展后的图像中的一个方块;

			Scalar  mean;
			Scalar  dev;
			meanStdDev(temp, mean, dev);

			varianceDst.at<float>(i - (winSize - 1) / 2, j - (winSize - 1) / 2) = dev.val[0];     ///一一对应赋值;
			meansDst.at<float>(i - (winSize - 1) / 2, j - (winSize - 1) / 2) = mean.val[0];
		}
	}


	return true;
}

4. 自动对比度参考

Mat autocontrost(Mat matface)
{
	//进行自动对比度校正
	double HistBlue[256] = { 0 };
	int bluemap[256] = { 0 };

	double dlowcut = 0.1;
	double dhighcut = 0.1;
	for (int i = 0; i < matface.rows; i++)
	{
		for (int j = 0; j < matface.cols; j++)
		{
			int iblue = matface.at<uchar>(i, j);
			HistBlue[iblue]++;
		}
	}
	int PixelAmount = matface.rows*matface.cols;
	int isum = 0;
	// blue
	int iminblue = 0; int imaxblue = 0;
	for (int y = 0; y < 256; y++)//这两个操作我基本能够了解了
	{
		isum = isum + HistBlue[y];
		if (isum >= PixelAmount * dlowcut*0.01)
		{
			iminblue = y;
			break;
		}
	}
	isum = 0;
	for (int y = 255; y >= 0; y--)
	{
		isum = isum + HistBlue[y];
		if (isum >= PixelAmount * dhighcut*0.01)
		{
			imaxblue = y;
			break;
		}
	}
	// 自动色阶
		//自动对比度
	int imin = 255; int imax = 0;
	if (imin > iminblue)
		imin = iminblue;
	iminblue = imin;
	if (imax < imaxblue)
		imax = imaxblue;
	imaxblue = imax;
	/
	//blue
	for (int y = 0; y < 256; y++)
	{
		if (y <= iminblue)
		{
			bluemap[y] = 0;
		}
		else
		{
			if (y > imaxblue)
			{
				bluemap[y] = 255;
			}
			else
			{
				//  BlueMap(Y) = (Y - MinBlue) / (MaxBlue - MinBlue) * 255      '线性隐射
				float ftmp = (float)(y - iminblue) / (imaxblue - iminblue);
				bluemap[y] = (int)(ftmp * 255);
			}
		}

	}
	//查表
	for (int i = 0; i < matface.rows; i++)
	{
		for (int j = 0; j < matface.cols; j++)
		{
			matface.at<uchar>(i, j) = bluemap[matface.at<uchar>(i, j)];
		}
	}
	return matface;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪易

给我来点鼓励吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值