2020-03-05 23:02:00 qq_29598161 阅读数 138
  • Erdas遥感影像处理入门实战教程(GIS思维)

    《Erdas遥感影像处理入门实战教程》以Erdas2010版本经典界面进行实战教学,设计12章内容,正式教学内容总共45课时,15个小时时长。从软件界面开始,到后的应用,适合入门级、初级、中级的人员学习、工作、教师教学参考。课程根据作者实际工作经验,以及采访学员需求,开展课程设计,实用加实战,会是你学习路上的好帮手。

    4618 人正在学习 去看看 黄晓军

本文主要参考 博客 OpenCV图像处理专栏十二 |《基于二维伽马函数的光照不均匀图像自适应校正算法》 中的代码
同时也参考了原论文: 刘志成,王殿伟,刘颖,刘学杰.基于二维伽马函数的光照不均匀图像自适应校正算法[J].北京理工大学学报,2016,36(02):191-196+214.

做了以下定制化内容:

  • 抑制高光(如日光,过曝)
  • 全局过暗全局使用BGR颜色(太暗了,再使用HSV颜色,极易出现彩色噪音,虽然色彩保留较好,但是效果和直接使用HSV颜色模式下V直方图均衡差不多)
  • 局部过暗使用HSV混合BGR(实验发现只使用HSV颜色,在过暗时容易出现彩色噪音,因为第亮度时,只改变V,会对HS产生较大变化,我猜的)
  • 不再使用平均亮度作为gamma校正标准,而是使用给定亮度
  • 不再使用3尺度加权高斯滤波求光照分量,而是使用一次均值滤波(追求速度,虽然不是基于Retinex 理论,但是发现效果差别不是很大)

优化部分:

  • 使用并行多线程,速度提升一倍
  • 更多基于opencv操作,在i5 mac 上8k图平均1.5s处理完
  • 对过暗和过亮部分做了优化

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>

class ParallelMix : public cv::ParallelLoopBody{
public:
    ParallelMix(cv::Mat& _v, cv::Mat& _v_i, cv::Mat& _src, const float _average): v(_v), v_i(_v_i), src(_src), average(_average){}
    void operator()(const cv::Range& range) const{
        for (int i = range.start; i < range.end; ++i){
            float *vp = v.ptr<float>(i);
            float *ip = v_i.ptr<float>(i);
            cv::Vec3f *srcp = src.ptr<cv::Vec3f>(i);
            
            for (int j = 0; j < src.cols; j++) {
                float dealta = ip[j] - average;
                float r = dealta / average;
                if(dealta > 0){
                    // inhibition of highlights
                    r *= powf((1 + dealta), 3);
                }
                float gamma = powf(2 , r );
                if(dealta > -0.4){
                    float x = powf(vp[j]  , gamma);
                    vp[j] =  x;
                    srcp[j] = cv::Vec3f(0, 0, 0);
                }else{
                    // to reduce noise
                    float dd = -0.4 - r;
                    float bx = powf(srcp[j][0], gamma+dd/5);
                    float gx = powf(srcp[j][1], gamma+dd/5);
                    float rx = powf(srcp[j][2], gamma+dd/5);
                    srcp[j][0] = bx * dd;
                    srcp[j][1] = gx * dd;
                    srcp[j][2] = rx * dd;
                    vp[j] = powf(vp[j]  , gamma) * (1 - dd);
                }
            }
        }
      }
private:
    cv::Mat& v;
    cv::Mat& v_i;
    cv::Mat& src;
    float average;
};

class ParallelBGR : public cv::ParallelLoopBody{
public:
    ParallelBGR(cv::Mat& _v_i, cv::Mat& _src, const float _average, const float _e): v_i(_v_i), src(_src), average(_average), e(_e){}
    void operator()(const cv::Range& range) const{
        for (int i = range.start; i < range.end; ++i){
            float *ip = v_i.ptr<float>(i);
            cv::Vec3f *srcp = src.ptr<cv::Vec3f>(i);
            for (int j = 0; j < src.cols; j++) {
                float dealta = ip[j] - average;
                float r = dealta / average;
                float gamma = powf(2 , r + e);
                float bx = powf(srcp[j][0], gamma);
                float gx = powf(srcp[j][1], gamma);
                float rx = powf(srcp[j][2], gamma);
                srcp[j][0] = bx;
                srcp[j][1] = gx;
                srcp[j][2] = rx;
            }
        }
    }
private:
    cv::Mat& v_i;
    cv::Mat& src;
    float average;
    float e;
};


//Adaptive Local Gamma Correction based on mean value adjustment
cv::Mat agc_mean_mix(cv::Mat& src, int kernel_size = -1, float average = 0.68) {
    cv::Mat src_hsv;
    std::vector<cv::Mat> hsv_channels(3);
    
    src.convertTo(src, CV_32FC3, 1 / 255.0);
    cv::cvtColor(src, src_hsv, cv::COLOR_BGR2HSV);
    cv::split(src_hsv, hsv_channels);
    cv::Mat& v = hsv_channels[2];
    
    // light component of V
    cv::Mat v_i;
    kernel_size = kernel_size == -1 ? std::min(src.rows, src.cols) / 30 : kernel_size;
    kernel_size = kernel_size % 2 ? kernel_size : kernel_size -1 ;
    // mean filtering replaces time-consuming gaussian filtering
    cv::blur(v, v_i,  cv::Size(kernel_size, kernel_size));
    
    
    float mean = cv::mean(v_i)[0];
    float e = mean - average;
    if(e > -0.4){
        cv::parallel_for_(cv::Range(0, src.rows), ParallelMix(v, v_i, src, average));
        
        cv::Mat dst_hsv;
        cv::merge(hsv_channels, dst_hsv);
        cv::cvtColor(dst_hsv, dst_hsv, cv::COLOR_HSV2BGR);
        dst_hsv.convertTo(dst_hsv, CV_8UC3, 255);
        
        cv::Mat dst_rgb;
        src.convertTo(dst_rgb, CV_8UC3, 255);
        
        cv::Mat dst;
        cv::add(dst_hsv, dst_rgb, dst);

        return dst;
    }else{
        // brightness too low global use bgr color
        cv::parallel_for_(cv::Range(0, src.rows), ParallelBGR(v_i, src, average, e));
        cv::Mat dst;
        src.convertTo(dst, CV_8UC3, 255);
        return dst;      
    }
    
}

结语

实验对比 查看

本文代码 链接 ,如果喜欢请给个star

2020-02-24 21:27:17 weixin_45709330 阅读数 454
  • Erdas遥感影像处理入门实战教程(GIS思维)

    《Erdas遥感影像处理入门实战教程》以Erdas2010版本经典界面进行实战教学,设计12章内容,正式教学内容总共45课时,15个小时时长。从软件界面开始,到后的应用,适合入门级、初级、中级的人员学习、工作、教师教学参考。课程根据作者实际工作经验,以及采访学员需求,开展课程设计,实用加实战,会是你学习路上的好帮手。

    4618 人正在学习 去看看 黄晓军

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

前言

这是OpenCV图像处理专栏的第十二篇文章,今天为大家介绍一个用于解决光照不均匀的图像自适应校正算法。光照不均匀其实是非常常见的一种状况,为了提升人类的视觉感受或者是为了提升诸如深度学习之类的算法准确性,人们在解决光照不均衡方面已经有大量的工作。一起来看看这篇论文使用的算法吧,论文名为:《基于二维伽马函数的光照不均匀图像自适应校正算法》。

算法原理

论文使用了Retinex的多尺度高斯滤波求取「光照分量」,然后使用了二「维Gamma函数」针对原图的「HSV空间的V(亮度)分量」进行亮度改变,得到结果。原理还是蛮简单的,因为是中文论文,且作者介绍得很清楚,我就不细说了,可以自己看论文,论文地址见附录。本文的重点在于对算法步骤的解读和OpenCV复现。

在这里插入图片描述

需要注意的点
文中公式5(二维Gamma变换) 有误,公式5为:在这里插入图片描述
其中γ\gamma的指数应该是mI(x,y)m-I(x,y),而不是I(x,y)mI(x,y)-m,如果使用后者会得到错误结果,应该是作者笔误了。

C++代码

Mat RGB2HSV(Mat src) {
	int row = src.rows;
	int col = src.cols;
	Mat dst(row, col, CV_32FC3);
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			float b = src.at<Vec3b>(i, j)[0] / 255.0;
			float g = src.at<Vec3b>(i, j)[1] / 255.0;
			float r = src.at<Vec3b>(i, j)[2] / 255.0;
			float minn = min(r, min(g, b));
			float maxx = max(r, max(g, b));
			dst.at<Vec3f>(i, j)[2] = maxx; //V
			float delta = maxx - minn;
			float h, s;
			if (maxx != 0) {
				s = delta / maxx;
			}
			else {
				s = 0;
			}
			if (r == maxx) {
				h = (g - b) / delta;
			}
			else if (g == maxx) {
				h = 2 + (b - r) / delta;
			}
			else {
				h = 4 + (r - g) / delta;
			}
			h *= 60;
			if (h < 0)
				h += 360;
			dst.at<Vec3f>(i, j)[0] = h;
			dst.at<Vec3f>(i, j)[1] = s;
		}
	}
	return dst;
}

Mat HSV2RGB(Mat src) {
	int row = src.rows;
	int col = src.cols;
	Mat dst(row, col, CV_8UC3);
	float r, g, b, h, s, v;
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			h = src.at<Vec3f>(i, j)[0];
			s = src.at<Vec3f>(i, j)[1];
			v = src.at<Vec3f>(i, j)[2];
			if (s == 0) {
				r = g = b = v;
			}
			else {
				h /= 60;
				int offset = floor(h);
				float f = h - offset;
				float p = v * (1 - s);
				float q = v * (1 - s * f);
				float t = v * (1 - s * (1 - f));
				switch (offset)
				{
				case 0: r = v; g = t; b = p; break;
				case 1: r = q; g = v; b = p; break;
				case 2: r = p; g = v; b = t; break;
				case 3: r = p; g = q; b = v; break;
				case 4: r = t; g = p; b = v; break;
				case 5: r = v; g = p; b = q; break;
				default:
					break;
				}
			}
			dst.at<Vec3b>(i, j)[0] = int(b * 255);
			dst.at<Vec3b>(i, j)[1] = int(g * 255);
			dst.at<Vec3b>(i, j)[2] = int(r * 255);
		}
	}
	return dst;
}

Mat work(Mat src) {
	int row = src.rows;
	int col = src.cols;
	Mat now = RGB2HSV(src);
	Mat H(row, col, CV_32FC1);
	Mat S(row, col, CV_32FC1);
	Mat V(row, col, CV_32FC1);
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			H.at<float>(i, j) = now.at<Vec3f>(i, j)[0];
			S.at<float>(i, j) = now.at<Vec3f>(i, j)[1];
			V.at<float>(i, j) = now.at<Vec3f>(i, j)[2];
		}
	}
	int kernel_size = min(row, col);
	if (kernel_size % 2 == 0) {
		kernel_size -= 1;
	}
	float SIGMA1 = 15;
	float SIGMA2 = 80;
	float SIGMA3 = 250;
	float q = sqrt(2.0);
	Mat F(row, col, CV_32FC1);
	Mat F1, F2, F3;
	GaussianBlur(V, F1, Size(kernel_size, kernel_size), SIGMA1 / q);
	GaussianBlur(V, F2, Size(kernel_size, kernel_size), SIGMA2 / q);
	GaussianBlur(V, F3, Size(kernel_size, kernel_size), SIGMA3 / q);
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			F.at <float>(i, j) = (F1.at<float>(i, j) + F2.at<float>(i, j) + F3.at<float>(i, j)) / 3.0;
		}
	}
	float average = mean(F)[0];
	Mat out(row, col, CV_32FC1);
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			float gamma = powf(0.5, (average - F.at<float>(i, j)) / average);
			out.at<float>(i, j) = powf(V.at<float>(i, j), gamma);
		}
	}
	vector <Mat> v;
	v.push_back(H);
	v.push_back(S);
	v.push_back(out);
	Mat merge_;
	merge(v, merge_);
	Mat dst = HSV2RGB(merge_);
	return dst;
}

效果

在这里插入图片描述

论文出处:https://wenku.baidu.com/view/3570f2c255270722182ef74e.html

2020-01-29 20:08:50 lyxleft 阅读数 271
  • Erdas遥感影像处理入门实战教程(GIS思维)

    《Erdas遥感影像处理入门实战教程》以Erdas2010版本经典界面进行实战教学,设计12章内容,正式教学内容总共45课时,15个小时时长。从软件界面开始,到后的应用,适合入门级、初级、中级的人员学习、工作、教师教学参考。课程根据作者实际工作经验,以及采访学员需求,开展课程设计,实用加实战,会是你学习路上的好帮手。

    4618 人正在学习 去看看 黄晓军

Matlab程序:

%%
%  基于二维伽马函数的光照不均匀图像自适应校正算法
%
%%
clc,close all;
tic;
im=imread('你的图片.jpg');
figure;
imshow(im);
title('原图');
[h,s,v]=rgb2hsv(im);    %转到hsv空间,对亮度h处理
% 高斯滤波
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;

 

2019-03-15 11:10:00 just_sort 阅读数 1473
  • Erdas遥感影像处理入门实战教程(GIS思维)

    《Erdas遥感影像处理入门实战教程》以Erdas2010版本经典界面进行实战教学,设计12章内容,正式教学内容总共45课时,15个小时时长。从软件界面开始,到后的应用,适合入门级、初级、中级的人员学习、工作、教师教学参考。课程根据作者实际工作经验,以及采访学员需求,开展课程设计,实用加实战,会是你学习路上的好帮手。

    4618 人正在学习 去看看 黄晓军

前言

这是OpenCV图像处理专栏的第十二篇文章,今天为大家介绍一个用于解决光照不均匀的图像自适应校正算法。光照不均匀其实是非常常见的一种状况,为了提升人类的视觉感受或者是为了提升诸如深度学习之类的算法准确性,人们在解决光照不均衡方面已经有大量的工作。一起来看看这篇论文使用的算法吧,论文名为:《基于二维伽马函数的光照不均匀图像自适应校正算法》。

算法原理

论文使用了Retinex的多尺度高斯滤波求取光照分量,然后使用了二维Gamma函数针对原图的HSV空间的V(亮度)分量进行亮度改变,得到结果。原理还是蛮简单的,因为是中文论文,且作者介绍得很清楚,我就不细说了,可以自己看论文,论文地址见附录。本文的重点在于对算法步骤的解读和OpenCV复现。

算法步骤

在这里插入图片描述

需要注意的点

文中公式5(二维Gamma变换) 有误,公式5为:

在这里插入图片描述
其中γ\gamma 的指数应该是mI(x,y)m-I(x,y),而不是I(x,y)mI(x,y)-m,如果使用后者会得到错误结果,应该是作者笔误了。

OpenCV C++代码复现

Mat RGB2HSV(Mat src) {
	int row = src.rows;
	int col = src.cols;
	Mat dst(row, col, CV_32FC3);
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			float b = src.at<Vec3b>(i, j)[0] / 255.0;
			float g = src.at<Vec3b>(i, j)[1] / 255.0;
			float r = src.at<Vec3b>(i, j)[2] / 255.0;
			float minn = min(r, min(g, b));
			float maxx = max(r, max(g, b));
			dst.at<Vec3f>(i, j)[2] = maxx; //V
			float delta = maxx - minn;
			float h, s;
			if (maxx != 0) {
				s = delta / maxx;
			}
			else {
				s = 0;
			}
			if (r == maxx) {
				h = (g - b) / delta;
			}
			else if (g == maxx) {
				h = 2 + (b - r) / delta;
			}
			else {
				h = 4 + (r - g) / delta;
			}
			h *= 60;
			if (h < 0)
				h += 360;
			dst.at<Vec3f>(i, j)[0] = h;
			dst.at<Vec3f>(i, j)[1] = s;
		}
	}
	return dst;
}

Mat HSV2RGB(Mat src) {
	int row = src.rows;
	int col = src.cols;
	Mat dst(row, col, CV_8UC3);
	float r, g, b, h, s, v;
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			h = src.at<Vec3f>(i, j)[0];
			s = src.at<Vec3f>(i, j)[1];
			v = src.at<Vec3f>(i, j)[2];
			if (s == 0) {
				r = g = b = v;
			}
			else {
				h /= 60;
				int offset = floor(h);
				float f = h - offset;
				float p = v * (1 - s);
				float q = v * (1 - s * f);
				float t = v * (1 - s * (1 - f));
				switch (offset)
				{
				case 0: r = v; g = t; b = p; break;
				case 1: r = q; g = v; b = p; break;
				case 2: r = p; g = v; b = t; break;
				case 3: r = p; g = q; b = v; break;
				case 4: r = t; g = p; b = v; break;
				case 5: r = v; g = p; b = q; break;
				default:
					break;
				}
			}
			dst.at<Vec3b>(i, j)[0] = int(b * 255);
			dst.at<Vec3b>(i, j)[1] = int(g * 255);
			dst.at<Vec3b>(i, j)[2] = int(r * 255);
		}
	}
	return dst;
}

Mat work(Mat src) {
	int row = src.rows;
	int col = src.cols;
	Mat now = RGB2HSV(src);
	Mat H(row, col, CV_32FC1);
	Mat S(row, col, CV_32FC1);
	Mat V(row, col, CV_32FC1);
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			H.at<float>(i, j) = now.at<Vec3f>(i, j)[0];
			S.at<float>(i, j) = now.at<Vec3f>(i, j)[1];
			V.at<float>(i, j) = now.at<Vec3f>(i, j)[2];
		}
	}
	int kernel_size = min(row, col);
	if (kernel_size % 2 == 0) {
		kernel_size -= 1;
	}
	float SIGMA1 = 15;
	float SIGMA2 = 80;
	float SIGMA3 = 250;
	float q = sqrt(2.0);
	Mat F(row, col, CV_32FC1);
	Mat F1, F2, F3;
	GaussianBlur(V, F1, Size(kernel_size, kernel_size), SIGMA1 / q);
	GaussianBlur(V, F2, Size(kernel_size, kernel_size), SIGMA2 / q);
	GaussianBlur(V, F3, Size(kernel_size, kernel_size), SIGMA3 / q);
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			F.at <float>(i, j) = (F1.at<float>(i, j) + F2.at<float>(i, j) + F3.at<float>(i, j)) / 3.0;
		}
	}
	float average = mean(F)[0];
	Mat out(row, col, CV_32FC1);
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			float gamma = powf(0.5, (average - F.at<float>(i, j)) / average);
			out.at<float>(i, j) = powf(V.at<float>(i, j), gamma);
		}
	}
	vector <Mat> v;
	v.push_back(H);
	v.push_back(S);
	v.push_back(out);
	Mat merge_;
	merge(v, merge_);
	Mat dst = HSV2RGB(merge_);
	return dst;
}

效果

原图1

效果图1

原图2
效果图2

结论

可以看到这个算法对光照不均匀的图像校正效果还是不错的,且没有像Retiex那样在亮度突变处出现色晕现象。

附录

  • 论文原文:https://wenku.baidu.com/view/3570f2c255270722182ef74e.html

同期文章


欢迎关注GiantPandaCV, 在这里你将看到独家的深度学习分享,坚持原创,每天分享我们学习到的新鲜知识。( • ̀ω•́ )✧

有对文章相关的问题,或者想要加入交流群,欢迎添加BBuf微信:

在这里插入图片描述

2019-07-26 15:20:07 u014157782 阅读数 781
  • Erdas遥感影像处理入门实战教程(GIS思维)

    《Erdas遥感影像处理入门实战教程》以Erdas2010版本经典界面进行实战教学,设计12章内容,正式教学内容总共45课时,15个小时时长。从软件界面开始,到后的应用,适合入门级、初级、中级的人员学习、工作、教师教学参考。课程根据作者实际工作经验,以及采访学员需求,开展课程设计,实用加实战,会是你学习路上的好帮手。

    4618 人正在学习 去看看 黄晓军

本篇博客主要给大家介绍的是对一篇论文中的亮度自适应算法的复现,感兴趣的同学可以进行尝试。
在视频和图像的采集过程中,由于受到地物环境复杂、物品之间相互遮挡以及环境光照条件多变等因素的影响,经常会导致场景的光照不均匀,主要表现为图像中亮的区域光线足够或者过强,而暗的区域照度不足,导致一些重要的细节信息无法凸显甚至被掩盖掉,严重影响了图像的视觉效果和应用价值,因此开展光照不均匀图像的校正研究,消除不均匀光照对图像的影响,已经成为当前图像处理领域的一个研究热点。
最近在做比赛上的一些东西,因为图片本身就存在着大量的噪声,我们在去燥的过程中发现了亮度不一导致的问题,因此采用了亮度自适应的算法来预处理完图像后,在进行下一步的去噪实验。
一、算法原理
基于二维伽马函数光照不均匀图像自适应校正算法,文献中算法的思路较简单,实现出来没有论文那么好的效果:

(1) 利用多尺度高斯函数去除场景的光照分量

(2) 然后构造了一种二维伽马函数,并利用光照分量的分布特性调整二维伽马函数的参数,降低光照过强区域的亮度值,提高光照过暗区域图像的亮度值,最终实现对光照不均匀图像的自适应校正处理。

利用高斯函数与源图像做卷积即可得到光照分量。G为高斯函数,F为源图像,I为光照分量。
在这里插入图片描述
在这里插入图片描述

二维伽马函数O(x,y),F是源图像,γ是亮度增强的指数值,由光照分量和光照分量的亮度均值m决定。

在这里插入图片描述

为避免RGB通道互相影响,整个处理过程是在HSV色彩空间进行的,对其中的亮度分量V进行处理,最后再从HSV空间转化到RGB空间。

注意:这里原论文的公式有问题,应该是作者的笔误,γ的指数应该是m-I(x,y),而不是I(x,y)-m。不然得到的结果不正确。简单分析一下:
底数小于1,那么指数越小,结果就会越大;指数越大,结果就会越小。伽马也是一个底数小于1的幂指数。

举个例子分析:按照论文的写法,设m=128,I(x,y)是较暗的地方灰度为64,γ是 ,是大于1的,底数小于1,则这个结果是小于底数的,暗的地方灰度变小

若I(x,y)是较亮的地方灰度为192,γ是根号0.5,,是小于1的,底数小于1,则这个结果是大于底数的。亮的地方灰度变大

那这样的结果是暗的地方变得更暗,亮的地方变得更亮,显然不对。
因此,在本文中,我特地把公式变了回来,希望各位看官看的开心。
二丶算法的流程图
在这里插入图片描述
三丶代码实现
下面我给出别人使用Matlab实现的算法

clc,close all;
tic;
im=imread('1128-2.jpg');
figure;
imshow(im);
title('原图');
[h,s,v]=rgb2hsv(im);    %转到hsv空间,对亮度h处理
% 高斯滤波
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;

下面是本人使用Python进行算法过程中遇到的一些问题和思考,代码我放在我的下载区,因为想赚点积分,大家谅解哈
最开始复现这个Matlab代码时,发现好像几乎没怎么变化,在我的文字部分,效果图如下:
在这里插入图片描述
在这里插入图片描述
于是乎,产生了怀疑,我便加上了亮度差矩阵,在求其平均值
在这里插入图片描述
在这里插入图片描述
均值再告诉我,对,你的猜想没错,几乎没发生变化,我靠,坑爹呢,看他们表演了半天,居然没怎么变化,是不是我给的图片亮度本来就还可以,没怎么变化呢,于是乎,我给了一张肉眼看起来就很暗的图片进行测试,效果如下:
在这里插入图片描述
再悄悄的看一眼亮度差的均值,是不是还是这种微乎其微的:
在这里插入图片描述
嗯,没错,发生了较大的变化了,但是还是很小啊,对吧,于是我开始思考哪里错了,想了很久,我发现了一个很大的问题,这是CSDN的代码,会不会作者那里思考错了,我再仔细看看,嗯,果然高斯卷积核不应该死图像的长和宽,源代码的高斯卷积核大小:
在这里插入图片描述
想到这,还有点小兴奋,立刻进行了改变试试,我直接把HSIZE改成了25
效果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
嗯,肉眼看起来变化还不是很大,于是乎,我再次对比了下差值:
在这里插入图片描述
我靠,这个值可以了,嗯,于是乎我就进行了批量的处理。
四、总结
通过本次的尝试,我发现了还是需要认真的做一件事情,不要全部相信别人,需要敢于质疑,并不断的去验证自己的想法。

没有更多推荐了,返回首页