图片的光照不均匀处理

一般的光照补偿算法

结合网上的资料发现比较多的去光照不均匀算法


基于二维伽马函数的光照不均匀图像自适应校正算法

本文发表于北京理工大学学报

该算法流程如图:

在这里插入图片描述

将图片投影到hsv域,对亮度v进行gamma校正,然后重新融合图片,得到校正后的图片。


参考网上的matlab代码

clc,close all;
tic;
im=imread('srcmpp.bmp');
%im=imread('qqq.jpg');
figure;
imshow(im);
title('原图');
[h,s,v]=rgb2hsv(im);    %转到hsv空间,对亮度v处理
% 高斯滤波
HSIZE= min(size(im,1),size(im,2));%高斯卷积核尺寸
q=sqrt(2);
SIGMA1=15;%论文里面的c
SIGMA2=80;
SIGMA3=250;
F1 = fspecial('gaussian',HSIZE,SIGMA1/q);
F2 = fspecial('gaussian',HSIZE,SIGMA2/q) ;
F3 = fspecial('gaussian',HSIZE,SIGMA3/q) ;
gaus1= imfilter(v, F1, 'replicate');
gaus2= imfilter(v, F2, 'replicate');
gaus3= imfilter(v, F3, 'replicate');
gaus=(gaus1+gaus2+gaus3)/3;    %多尺度高斯卷积,加权,权重为1/3
% gaus=(gaus*255);
figure;
imshow(gaus,[]);
title('光照分量');
%二维伽马卷积
m=mean(gaus(:));
[w,height]=size(v);
out=zeros(size(v));
gama=power(0.5,((m-gaus)/m));%根据公式gamma校正处理,论文公式有误
out=(power(v,gama));
figure;
imshow(out,[]);
rgb=hsv2rgb(h,s,out);   %转回rgb空间显示
figure;
imshow(rgb);
title('处理结果')
toc;


一种基于亮度均衡的图像阈值分割技术

这个方法来自合工大


1. 图片分块

2. 分块求均值

3. 全局均值-分块均值

4. 对得到的差插值处理

5. 原图-差值得到亮度均衡后的图片


针对高亮和反光有比较好的效果,使用C++函数的处理速度也很快。参考博客获得详细解释及代码

这个方法会导致亮的部分变暗,暗的部分变亮,其实很好理解,因为分块的区域相对于全局的均值的差必定是有正有负的,所以亮的部分会被削弱,暗的部分会被增强。

我个人认为这个算法是比较好一点的,至少处理效果很明显

参考网上的C++代码

void unevenLightCompensate(Mat &image, int blockSize)
{
	if (image.channels() == 3) cvtColor(image, image, 7);
	double average = mean(image)[0];
	int rows_new = ceil(double(image.rows) / double(blockSize));
	int cols_new = ceil(double(image.cols) / double(blockSize));
	Mat blockImage;
	blockImage = Mat::zeros(rows_new, cols_new, CV_32FC1);
	for (int i = 0; i < rows_new; i++)
	{
		for (int j = 0; j < cols_new; j++)
		{
			int rowmin = i * blockSize;
			int rowmax = (i + 1)*blockSize;
			if (rowmax > image.rows) rowmax = image.rows;
			int colmin = j * blockSize;
			int colmax = (j + 1)*blockSize;
			if (colmax > image.cols) colmax = image.cols;
			Mat imageROI = image(Range(rowmin, rowmax), Range(colmin, colmax));
			double temaver = mean(imageROI)[0];
			blockImage.at<float>(i, j) = temaver;
		}
	}
	blockImage = blockImage - average;
	Mat blockImage2;
	resize(blockImage, blockImage2, image.size(), (0, 0), (0, 0), INTER_CUBIC);
	Mat image2;
	image.convertTo(image2, CV_32FC1);
	Mat dst = image2 - blockImage2;
	dst.convertTo(image, CV_8UC1);
}


opencv函数illuminationChange

这个函数需要提供mask,也就意味着需要预先进行二值化,从而确定需要修正光照的位置,所以不太好用。


亮度均衡与sgm结果

3D暂时不需要亮度均衡

1. 速度慢

2. 效果没有肉眼可见的提升

3. 效果的测试并不好量化


利用双边滤波的实时去高光

image.png

原图,论文代码,网上代码

int highlight_remove_Chi(IplImage* src, IplImage* dst, double Re)
{
	int height = src->height;
	int width = src->width;
	int step = src->widthStep;
	int i = 0, j = 0;
	unsigned char R, G, B, MaxC;
	double alpha, beta, alpha_r, alpha_g, alpha_b, beta_r, beta_g, beta_b, temp = 0, realbeta = 0, minalpha = 0;
	double gama, gama_r, gama_g, gama_b;
	unsigned char* srcData;
	unsigned char* dstData;
	for(i = 0; i < height; i++)
	{
		srcData = (unsigned char*)src->imageData + i * step;
		dstData = (unsigned char*)dst->imageData + i * step;
		for(j = 0; j < width; j++)
		{
			R = srcData[j * 3];
			G = srcData[j * 3 + 1];
			B = srcData[j * 3 + 2];

			alpha_r = (double)R / (double)(R + G + B);
			alpha_g = (double)G / (double)(R + G + B);
			alpha_b = (double)B / (double)(R + G + B);
			alpha = max(max(alpha_r, alpha_g), alpha_b);
			MaxC = max(max(R, G), B);// compute the maximum of the rgb channels
			minalpha = min(min(alpha_r, alpha_g), alpha_b);
			beta_r = 1 - (alpha - alpha_r) / (3 * alpha - 1);
			beta_g = 1 - (alpha - alpha_g) / (3 * alpha - 1);
			beta_b = 1 - (alpha - alpha_b) / (3 * alpha - 1);
			beta = max(max(beta_r, beta_g), beta_b);//将beta当做漫反射系数,则有                 // gama is used to approximiate the beta
			gama_r = (alpha_r - minalpha) / (1 - 3 * minalpha);
			gama_g = (alpha_g - minalpha) / (1 - 3 * minalpha);
			gama_b = (alpha_b - minalpha) / (1 - 3 * minalpha);
			gama = max(max(gama_r, gama_g), gama_b);

			temp = (gama*(R + G + B) - MaxC) / (3 * gama - 1);
			//beta=(alpha-minalpha)/(1-3*minalpha)+0.08;
			//temp=(gama*(R+G+B)-MaxC)/(3*gama-1);
			dstData[j * 3] = R - (unsigned char)(temp + 0.5);
			dstData[j * 3 + 1] = G - (unsigned char)(temp + 0.5);
			dstData[j * 3 + 2] = B - (unsigned char)(temp + 0.5);
		}
	}
	return 1;
}



调用该函数需要Mat 与IplImage的相互转化

Mat src=imread("xxx.jpg");
Mat dst;
	IplImage* pBinary = &IplImage(src);
	IplImage* pBinary2 = &IplImage(src);// = &IplImage(dst);
	//深拷贝只要再加一次复制数据:
	IplImage *input = cvCloneImage(pBinary);
	if (highlight_remove_Chi(input, pBinary2, 1.0)) {
		dst = cvarrToMat(pBinary2);
		//	imshow("image1", src);
		imshow("save1", dst);
		waitKey();
	}


网上的代码应该是缺少了优化迭代的过程,对于大块的反光几乎没有办法处理

————————————————

版权声明:本文为CSDN博主「VeraWin」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/TiffanyXYf/article/details/106543238


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年4月    »
1234567
891011121314
15161718192021
22232425262728
2930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864