图像增强

常见的图像增强算法有;直方图均衡,拉普拉斯算子,对数log变换,伽玛变换。

1.对数log变换:

void main()
{	
	Mat src = imread("C:/Users/Administrator/Desktop/add/1.jpg");
	imshow("src",src);
	Mat temp(src.size(),CV_32FC3);
	for (int i = 0; i < src.rows; ++i)
	{
		for (int j = 0; j < src.cols; ++j)
		{
			temp.at<Vec3f>(i, j)[0] = log(1 + src.at<Vec3b>(i, j)[0]);
			temp.at<Vec3f>(i, j)[1] = log(1 + src.at<Vec3b>(i, j)[1]);
			temp.at<Vec3f>(i, j)[2] = log(1 + src.at<Vec3b>(i, j)[2]);
		}
	}
	normalize(temp, temp, 0, 255, CV_MINMAX);
	convertScaleAbs(temp,temp);
	imshow("temp",temp);	
	waitKey(0);
	
}

如果temp直接定义为src.type()类型,最后的图感觉都点失真。converScaleAbs必不可少,否则最后的输出只有部分图像。这里的log是以e为底数。log还有其它几种形式,分别为:log10(即以10为底)、log2(即以2位底)、log1p(以e为底,指数加1)、logb(即2^{n}\leqslant 指数指数,返回n)。其中normalize可以看这个。对数的底数越大,变换后图像的对比度越大。对数变换对图像对比度偏低的效果比较好。

2.伽玛变换:

void main()
{	
	Mat src = imread("C:/Users/Administrator/Desktop/add/1.jpg");
	imshow("src",src);
	Mat temp(src.size(),CV_32FC3);
	for (int i = 0; i < src.rows; ++i)
	{
		for (int j = 0; j < src.cols; ++j)
		{		
			temp.at<Vec3f>(i, j)[0] = pow(src.at<Vec3b>(i, j)[0],0.4);
			temp.at<Vec3f>(i, j)[1] = pow(src.at<Vec3b>(i, j)[1], 0.4);
			temp.at<Vec3f>(i, j)[2] = pow(src.at<Vec3b>(i, j)[2], 0.4);
		}
	}
	normalize(temp, temp, 0, 255, CV_MINMAX);
	convertScaleAbs(temp,temp);
	imshow("temp",temp);
	waitKey(0);
	
}

converScaleAbs必不可少,否则最后的输出只有部分图像。以1为分界点,pow中的幂指数越大,图像就会越暗;幂指数越小,图像就会越亮。

3.直方图均衡:

void main()
{
	
	Mat src = imread("C:/Users/Administrator/Desktop/add/1.jpg");
	imshow("src",src);
	vector<Mat> lis;
	split(src,lis);
	for (int i = 0; i < 3; i++)
	{
		equalizeHist(lis[i],lis[i]);
	}
	Mat dst;
	merge(lis,dst);
	imshow("dst",dst);
	waitKey(0);
	
}

其实还可以先将src转为hsv颜色空间,然后split,直方图均衡V分量,效果和均衡RGB一样。均衡RGB容易出现失真,直接均衡亮度V比较好。

void main()
{

	Mat src = imread("C:/Users/Administrator/Desktop/add/1.jpg");
	imshow("src", src);
	cvtColor(src, src, CV_BGR2HSV);
	vector<Mat> lis;
	split(src, lis);
	equalizeHist(lis[2], lis[2]);
	Mat dst;
	merge(lis, dst);
	cvtColor(dst,dst,CV_HSV2BGR);
	imshow("dst", dst);
	waitKey(0);

}

4.拉普拉斯算子:

算子: 

                        A=\begin{bmatrix} 0 & -1 & 0\\ -1& 5 &-1 \\ 0& -1&0 \end{bmatrix},用它作为卷积核对原图卷积,可以达到锐化的效果。

void main()
{	
	Mat src = imread("C:/Users/Administrator/Desktop/add/1.jpg");
	imshow("src",src);
	Mat A=(Mat_<int>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
	Mat dst;
	filter2D(src,dst,CV_8UC3,A);
	imshow("dst",dst);
	waitKey(0);	
}

可以自己构造一个核,核内的所有元素(即权重)的和为1,即可构成锐化核。如果感兴趣的像素已经与其临近像素有一点差别,卷积一个这样的核,差别就会增加。这样就会让图像锐化,因为该像素的值与临近像素值之间的差距变大。核内的所有元素(即权重)的和为0,就会得到一个边缘检测核,把边缘转为白色,把非边缘区域转为黑色。

拉普拉斯算子有如下几种(《数字图像处理》第三版P99):

\fn_cm A=\begin{bmatrix} 0 & -1 & 0\\ -1& 4 &-1 \\ 0& -1&0 \end{bmatrix}A=\begin{bmatrix} -1 & -1 & -1\\ -1& 8 &-1 \\ -1& -1&-1 \end{bmatrix}A=\begin{bmatrix} 0 & 1 & 0\\ 1& -4 &1 \\ 0& 1&0 \end{bmatrix}A=\begin{bmatrix} 1 & 1 & 1\\ 1& -8 &1 \\ 1& 1&1 \end{bmatrix}

若使用的核中间系数为正,将原图加上拉普拉斯变换后的图就可以得到锐化后的图;若使用的核的中间系数为负,将原图减去拉普拉斯变换后的图就可以得到锐化后的图。

void main()
{
	Mat src = imread("C:/Users/Administrator/Desktop/add/1.jpg");
	imshow("src", src);
	Mat A = (Mat_<int>(3, 3) << 0, -1, 0, -1, 4, -1, 0, -1, 0);
	Mat dst;
	filter2D(src, dst, CV_8UC3, A);
	imshow("dst", dst);
	Mat cap;
	cap = src + dst;
	imshow("cap",cap);
	waitKey(0);
}

参考:

OpenCV图像增强算法实现

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值