图像增强处理之:同态滤波与Retinex算法(一)同态滤波

链接中文章,讲述了基于同态滤波和retinex算法进行图像去雾的算法,本篇对同态滤波和retinex算法进行介绍。

在生活中会得到这样的图像,动态范围很大,感兴趣的部分的灰度却很暗,范围很小,灰度层次和细节没有办法辨认,用一般的灰度线性变换法是不行的,因为扩展灰度级虽可以提高物体图像的 因为扩展灰度级虽可以提高物体图像的反差,但会使动态范围变大。而压缩灰 反差,但会使动态范围变大。而压缩灰度级,虽可以减少动态范围,但物体灰 度级,虽可以减少动态范围,但物体灰
度层次和细节就会更看不清。 度层次和细节就会更看不.这时我们需要采用同态滤波。同态滤波是一种在频域中同时将图像亮度范围进行压缩和将图像对比度进行增强的方法。

同态滤波

 

节选自百度百科里的一段话:同态滤波的基本原理是:将像元灰度值看作是照度和反射率两个组份的产物。由于照度相对变化很小,可以看作是图像的低频成份,而反射率则是高频成份。通过分别处理照度和反射率对像元灰度值的影响,达到揭示阴影区细节特征的目的。同态滤波处理的基本流程如下:

S(x,y)---->Log---->DFT---->频域滤波---->IDFT---->Exp---->T(x,y)

其中S(x,y)表示原始图像;T(x,y)表示处理后的图像;Log 代表对数运算;DFT 代表傅立叶变换(实际操作中运用快速傅立叶变换FFT);IDFT 代表傅立叶逆变换(实际操作中运用快速傅立叶逆变换IFFT);Exp 代表指数运算。

 

下面附一段更直观,带公式的讲解,作者:风吹夏天

对于一副图像f(x,y)可由照射分量i(x,y)和反射分量r(x,y)的乘积,即

f(x,y) =i(x,y)r(x,y)
上式不能直接用于对照度和反射的频率分量进行操作,因此上式取对数

Inf(x,y)=lni(x,y)+lnr(x,y)

对上式两边取傅里叶变换,

\Im \{ Inf(x,y)\} = \Im \{ Ini(x,y)\} + \Im \{ Inr(x,y)\}
图像的照射分量通常由慢的空间变化来表征,而反射分量往往引起突变,特别是在不同物体的连接部分。这些特性导致图像取对数后的傅里叶变换的低频成分与照射相联系,而高频成分与反射相联系。
使用同态滤波器可以更好地控制照射分量和反射分量。这种控制器需要指定一个滤波器函数H(u,v),它可用不同的可控方法影响傅里叶变换的低频和高频。如果γLγH选定,而γL<1且γH>1,那么滤波器函数趋近于衰减低频(照射)的贡献,而增强高频反射的贡献。最终结果是同时进行动态范围的压缩和对比度的增强。
这里写图片描述

 

H({\rm{u,v) = (}}{\gamma _H} - {\gamma _L})[1 - {e^{ - c[{D^2}(u,v)/D_0^2]}}] + {\gamma _L}

同态滤波的目的目的:消除不均匀照度的影响而又不损失图象细节。其依据:图象的灰度由照射分量和反射分量合成。反射分量反映图象内容,随图象细节不同在空间上作快速变化。照射分量在空间上通常均具有缓慢变化的性质。照射分量的频谱落在空间低频区域,反射分量的频谱落在空间高频区。

参考1:

function I3 = homofilter(I)    %同态滤波函数
subplot(1,2,1),imshow(I);title('同态滤波之前原始图像');     
I=double(rgb2gray(I));    
[M,N]=size(I);    
rL=0.5;    
rH=5;%可根据需要效果调整参数    
c=3;    
d0=9;    
I1=log(I+1);%取对数    
FI=fft2(I1);%傅里叶变换    
n1=floor(M/2);    
n2=floor(N/2);    
for i=1:M    
    for j=1:N    
        D(i,j)=((i-n1).^2+(j-n2).^2);    
        H(i,j)=(rH-rL).*(exp(c*(-D(i,j)./(d0^2))))+rL;%高斯同态滤波    
    end    
end    
I2=ifft2(H.*FI);%傅里叶逆变换    
I3=real(exp(I2));    
subplot(1,2,2),imshow(I3,[]);title('同态滤波增强后');  

测试函数及结果:

%% 同台滤波测试函数
clc,close all,clear all;
img=imread('../image/1.jpg');
I3 = homofilter(img);

上面程序是将RGB图像灰度化之后再同态滤波的,在网上没找到直接针对彩色图像同态滤波处理的,所以我在上面程序基础上写了针对彩色图像的程序:

 

function I3 = homofilterColor(I)    
subplot(1,2,1),imshow(I);title('同态滤波之前原始图像');     
% I=double(rgb2gray(I)); 
I=double(I);
[M,N,channals]=size(I);    
rL=0.5;    
rH=5;%可根据需要效果调整参数    
c=3;    
d0=9;  
I3=I;
for ch=1:channals
I1=log(I(:,:,ch)+1);%取对数    
FI=fft2(I1);%傅里叶变换    
n1=floor(M/2);    
n2=floor(N/2);    
for i=1:M    
    for j=1:N    
        D(i,j)=((i-n1).^2+(j-n2).^2);    
        H(i,j)=(rH-rL).*(exp(c*(-D(i,j)./(d0^2))))+rL;%高斯同态滤波    
    end    
end    
I2=ifft2(H.*FI);%傅里叶逆变换    
I3(:,:,ch)=real(exp(I2));
end

minV=min(min(min(I3)));
maxV=max(max(max(I3)));
for ch=1:channals
for i=1:M   
        for j=1:N    
            I3(i,j,ch)=255* (I3(i,j,ch)-minV)./(maxV-minV);
        end
end
end

subplot(1,2,2),imshow(uint8(I3));title('同态滤波增强后');  

 

 

 

下面是我参照matlab程序在opencv的实现程序,针对灰度图像:

 

#include <opencv2\opencv.hpp>
#include <iostream>
#include <math.h>

using namespace cv;
using namespace std;
//同态滤波
void my_HomoFilter(Mat srcImg, Mat &dst)
{
	srcImg.convertTo(srcImg, CV_64FC1);
	dst.convertTo(dst, CV_64FC1);
	//第一步,取对数
	for (int i = 0; i < srcImg.rows; i++)
	{
		double* srcdata = srcImg.ptr<double>(i);
		double* logdata = srcImg.ptr<double>(i);
		for (int j = 0; j < srcImg.cols; j++)
		{
			logdata[j] = log(srcdata[j] + 1);
		}
	}
	//第二步,傅里叶变换
	Mat mat_dct = Mat::zeros(srcImg.rows, srcImg.cols, CV_64FC1);
	dct(srcImg, mat_dct);
	namedWindow("dct", CV_WINDOW_FREERATIO);
	imshow("dct", mat_dct);
	//第三步,频域滤波
	Mat H_u_v;
	int n1 = floor(srcImg.rows / 2);
	int n2 = floor(srcImg.cols / 2);
	double gammaH = 5;
	double gammaL = 0.5;
	double C = 3;
	double d0 = 9.0;
	double d2 = 0;
	H_u_v = Mat::zeros(srcImg.rows, srcImg.cols, CV_64FC1);

	double totalWeight = 0.0;
	for (int i = 0; i < srcImg.rows; i++)
	{
		double * dataH_u_v = H_u_v.ptr<double>(i);
		for (int j = 0; j < srcImg.cols; j++)
		{
			d2 = pow(i-n1, 2.0) + pow(j-n2, 2.0);
			dataH_u_v[j] = (gammaH - gammaL)*exp(C*(-d2 / (d0*d0))) + gammaL;
		}
	}
	H_u_v.ptr<double>(0)[0] = 1.5;
	mat_dct = mat_dct.mul(H_u_v);
	//第四步,傅里叶逆变换
	idct(mat_dct, dst);

	//第五步,取指数运算
	for (int i = 0; i < srcImg.rows; i++)
	{
		double* srcdata = dst.ptr<double>(i);
		double* dstdata = dst.ptr<double>(i);
		for (int j = 0; j < srcImg.cols; j++)
		{
			dstdata[j] = exp(srcdata[j]);
		}
	}
	dst.convertTo(dst, CV_8UC1);
}

void main()
{
	Mat src = imread("D:\\fcq_proMatlab\\vessel_edge_extration\\image\\homofilter.jpg",0);
	namedWindow("src:", CV_WINDOW_FREERATIO);
	imshow("src:", src);
	Mat dst(src.rows, src.cols, src.type());
	my_HomoFilter(src, dst);
	namedWindow("dst:", CV_WINDOW_FREERATIO);
	imshow("dst:", dst);
	waitKey();
	system("pause");
}

 

效果图如下:

参考:

  1. http://blog.csdn.net/scottly1/article/details/42705271
  2. http://blog.csdn.net/lilingyu520/article/details/46654265
  3. http://blog.csdn.net/bluecol/article/details/45788803
  • 26
    点赞
  • 218
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
好的,关于使用同态滤波对RGB图像进行增强,可以按照以下步骤进行: 1. 将RGB图像转换为灰度图像。 2. 对灰度图像进行同态滤波处理同态滤波是一种能够平衡图像亮度和对比度的滤波方法,能够有效地去除图像中的噪声和增强细节。同态滤波的具体实现方法可以使用MATLAB中的imfilter函数。 3. 将同态滤波处理后的灰度图像转换回RGB图像。 下面是一个使用MATLAB实现同态滤波的示例代码: ```matlab % 读取RGB图像 rgb = imread('example.jpg'); % 将RGB图像转换为灰度图像 gray = rgb2gray(rgb); % 设置同态滤波参数 a = 0.25; b = 1.5; T = 0.01; N = 15; % 对灰度图像进行同态滤波处理 filtered = homomorphicFilter(gray, a, b, T, N); % 将同态滤波处理后的灰度图像转换回RGB图像 enhanced = cat(3, filtered, filtered, filtered); % 显示结果 figure; subplot(1, 2, 1); imshow(rgb); title('原始图像'); subplot(1, 2, 2); imshow(enhanced); title('增强后的图像'); % 定义同态滤波函数 function filtered = homomorphicFilter(gray, a, b, T, N) % 将灰度图像转换为双精度浮点型 gray = im2double(gray); % 计算图像的对数变换 logImage = log(1 + gray); % 计算图像的傅里叶变换 f = fft2(logImage); % 计算滤波器H(u,v) [M, N] = size(f); u = 1:M; v = 1:N; [V, U] = meshgrid(v, u); H = (b - a) * (1 - exp(-T * (U.^2 + V.^2))) + a; % 对图像进行同态滤波 filtered = zeros(size(gray)); for i = 1:N for j = 1:M filtered(i, j) = real(sum(sum(H .* f(i, j) ./ H))); end end % 取指数变换得到最终结果 filtered = exp(filtered) - 1; filtered = (filtered - min(filtered(:))) / (max(filtered(:)) - min(filtered(:))); end ``` 上述代码中,使用了一个名为`homomorphicFilter`的函数来实现同态滤波函数的输入参数包括灰度图像`gray`、同态滤波的参数`a`、`b`、`T`和`N`。函数的输出是同态滤波处理后的灰度图像`filtered`。 在主程序中,首先读取RGB图像,然后将其转换为灰度图像。接着,设置同态滤波的参数,并调用`homomorphicFilter`函数对灰度图像进行同态滤波处理。最后,将同态滤波处理后的灰度图像转换回RGB图像,并显示原始图像和增强后的图像。 需要注意的是,同态滤波的参数`a`、`b`、`T`和`N`需要根据具体情况进行调整,以达到最佳的增强效果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值