目前来看,sgm算法对于布匹的计算能力较好。细节越突出,计算结果越好。有些图片内容,相机的聚焦能力以及分辨率不够的话,就会计算的不够好。
亮度对比度在一定范围内改变对于sgm计算视差结果影响不大。如下图是改变亮度对比度之后计算的视差与原视差的差。
结合网上的资料发现比较多的去光照不均匀算法
本文发表于北京理工大学学报
该算法流程如图:
将图片投影到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;
这个方法来自合工大
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(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);
}
这个函数需要提供mask,也就意味着需要预先进行二值化,从而确定需要修正光照的位置,所以不太好用。
3D暂时不需要亮度均衡
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();
}
网上的代码应该是缺少了优化迭代的过程,对于大块的反光几乎没有办法处理