掘金 人工智能 05月06日 20:08
OpenCV 笔记(38):同态滤波
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

同态滤波是一种图像增强技术,旨在解决图像光照不均匀和细节对比度不足的问题。其核心思想是将图像分解为光照分量(低频)和反射分量(高频),通过对数变换、傅里叶变换将图像转换到频域,设计滤波器分别调整这两个分量,再通过逆变换恢复图像。高斯型同态滤波器是常用的一种,通过增强高频、衰减低频来改善图像质量。该技术在OpenCV C++中可以实现,对灰度图和彩色图都适用,能有效提高图像的视觉效果和可分析性。

💡**核心思想**:同态滤波的核心在于将图像分解为光照分量和反射分量,并在频域中分别处理,以校正非均匀光照并增强细节对比度。

🧮**算法流程**:算法包含对数变换、傅里叶变换、滤波、逆傅里叶变换和指数运算。对数变换将乘性光照和反射分量转换为加性,便于在频域进行处理。傅里叶变换将图像分解为不同频率的成分,滤波器用于增强或衰减特定频率,最后通过逆变换和指数运算恢复图像。

🛠️**OpenCV C++实现**:文章提供了详细的OpenCV C++代码示例,展示了如何构造高斯型高通同态滤波器,并将其应用于单通道和彩色图像。代码包括创建滤波器、傅里叶变换、滤波、逆变换以及图像归一化等关键步骤。

📈**高斯型同态滤波器**:高斯型同态滤波器通过参数γL(低频增益)和γH(高频增益)来调节光照和细节的权重,c控制滤波器的陡峭程度,D0是截止频率。这种滤波器能有效衰减低频成分(减少光照不均),并增强高频成分(增强细节和对比度)。

1. 同态滤波

同态滤波(Homomorphic Filtering)是一种经典的图像增强方法,主要用于同时校正图像的 非均匀光照增强细节对比度

同态滤波的核心思想是将图像的光照分量(低频)和反射分量(高频)分离,并分别进行调整,最终改善图像的对比度和细节。

2. 算法流程

2.1 图像模型

图像可表示为光照分量i(x,y)i(x,y)和反射分量r(x,y)r(x,y)的乘积:f(x,y)=i(x,y)r(x,y)f(x,y)=i(x,y)⋅r(x,y)

其中:

2.2 对数变换

为了能够独立处理光照和反射,同态滤波的第一步是对图像的像素值取对数。因为在数学上,乘法运算在取对数后会变成加法运算。

z(x,y)=lnf(x,y)=lni(x,y)+lnr(x,y)z(x,y) = lnf(x,y)=lni(x,y)+lnr(x,y)

此后,光照分量和反射分量在频域中更易于分离。

2.3 傅里叶变换

对取对数变换后的图像z(x,y)z(x,y)进行傅里叶变换,转换到频域,得到频谱Z(u,v)Z(u,v)

Z(u,v)=F{z(x,y)}Z(u, v)=\mathcal{F}\{z(x, y)\}

这样做的目的是将图像分解为不同频率的成分。

2.4 设计滤波器

设计一个合适的滤波器函数H(u,v)H(u,v),并在频域中将频谱 Z(u,v)Z(u,v) 与该滤波器相乘,得到滤波后的频谱 S(u,v)S(u,v)

S(u,v)=H(u,v)Z(u,v)S(u,v)=H(u,v)⋅Z(u,v)

根据频率成分的特性进行增强或衰减。一个典型的同态滤波器会衰减低频成分(减少光照不均),并增强高频成分(增强细节和对比度)。

因此,滤波器函数 H(u,v)H(u,v) 的设计是同态滤波的关键,不同的滤波器会产生不同的增强效果。

常见的同态滤波器形式包括:

这里,我们以高斯型同态滤波器为例,它是一种基于高斯函数设计的频域滤波器,结合同态滤波框架与高斯函数的频域特性,对图像的光照分量(低频)和反射分量(高频)进行差异化调整。我们用以下公式来表示高斯同态滤波器的传递函数:

H(u,v)=(γHγL)[1ecD2(u,v)D02]+γLH(u, v)=\left(\gamma_{H}-\gamma_{L}\right)\left[1-e^{-c \frac{D^{2}(u, v)}{D_{0}^{2}}}\right]+\gamma_{L}

其中,

这个形式是一种 高斯型高通滤波器,嵌入到同态滤波的增益控制中,用来调节低频(光照分量)和高频(细节分量)的权重。

2.5 傅里叶逆变换

将滤波后的频谱 S(u,v)S(u,v) 转换回空间域,得到滤波后的对数图像 s(x,y)s(x,y)

s(x,y)=F1{S(u,v)}s(x, y)=\mathcal{F}^{-1}\{S(u, v)\}

2.6 指数运算

对图像 s(x,y)s(x,y) 的每个像素值进行指数运算,得到最终的增强图像 g(x,y)g(x,y)

g(x,y)=exp(s(x,y))g(x,y)=\exp(s(x,y))

这个步骤是为了恢复原始图像的尺度和亮度范围。由于第一步进行了对数运算,这里需要进行指数运算来还原。

总结一下整个算法的流程

原始图像 → 对数变换 → 傅里叶变换 → 同态滤波 → 逆傅里叶变换 → 指数变换 → 输出图像

3. 使用 OpenCV C++ 实现同态滤波

下面的例子,展示了如何基于上述的算法流程构建单通道同态滤波,以及如何构建高斯型高通同态滤波器。对于彩色图像而言,需要先分离出 B、G、R 通道,每个通道单独使用同态滤波,最后再合并回彩色图像。

#include <opencv2/opencv.hpp>#include <iostream>using namespace cv;using namespace std;// 构造高斯型高通同态滤波器Mat createHighPassFilter(Size size, float gammaH, float gammaL, float c, float D0) {    Mat H(size, CV_32F);    Point center = Point(size.width / 2, size.height / 2);    for (int u = 0; u < size.height; u++) {        for (int v = 0; v < size.width; v++) {            float D = sqrt(pow(u - center.y, 2) + pow(v - center.x, 2));            H.at<float>(u, v) = (gammaH - gammaL) * (1.0f - exp(-c * (D * D) / (D0 * D0))) + gammaL;        }    }    return H;}// 单通道同态滤波Mat homomorphicFilter(const Mat& image, float gammaH, float gammaL, float c, float D0) {    Mat floatImg;    image.convertTo(floatImg, CV_32F);    // 转换为 float 类型,方便后续计算    floatImg += 1;                      // 防止 log(0) 出现无穷大    log(floatImg, floatImg);            // 对图像取对数:ln(f(x, y))    // 对图像扩展到最佳 DFT 尺寸    int m = cv::getOptimalDFTSize(image.rows);    int n = cv::getOptimalDFTSize(image.cols);    Mat padded;    copyMakeBorder(floatImg, padded, 0, m - image.rows, 0, n - image.cols, BORDER_CONSTANT, Scalar::all(0));    // 创建复数矩阵,实部为 padded,虚部为 0    Mat planes[] = { padded, Mat::zeros(padded.size(), CV_32F) };    Mat complexI;    merge(planes, 2, complexI);    // 进行傅里叶变换    dft(complexI, complexI);    // 创建高通同态滤波器,尺寸和 padded 一致    Mat H = createHighPassFilter(padded.size(), gammaH, gammaL, c, D0);    // 将频谱从笛卡尔坐标转换为极坐标(幅值和相位)    split(complexI, planes);    Mat mag, phase;    cartToPolar(planes[0], planes[1], mag, phase);    // 在频率域应用滤波器(只对幅值部分)    mag = mag.mul(H);    // 将极坐标转换回笛卡尔坐标    polarToCart(mag, phase, planes[0], planes[1]);    merge(planes, 2, complexI);    // 傅里叶逆变换,回到空域    idft(complexI, complexI);    // 提取实部,去掉填充部分    split(complexI, planes);    Mat realI = planes[0](Rect(0, 0, image.cols, image.rows));    // 归一化到 [0, 10],避免指数溢出    normalize(realI, realI, 0, 10, NORM_MINMAX);    // 对结果取指数,还原到线性空间    Mat img_out;    exp(realI, img_out);    // 最后归一化到 [0, 255] 并转换为 8 位图像    double minVal, maxVal;    minMaxLoc(img_out, &minVal, &maxVal);    img_out.convertTo(img_out, CV_8U, 255.0 / (maxVal - minVal), -minVal * 255.0 / (maxVal - minVal));    return img_out;}int main() {    Mat src = imread(".../landscape.jpg", IMREAD_UNCHANGED);    if (src.empty()) {        cout << "无法加载图像" << endl;        return -1;    }    Mat result;    if (src.channels() == 1) {        // 灰度图像处理        result = homomorphicFilter(src, 1.5f, 0.5f, 1.0f, 30.0f);    } else if (src.channels() == 3) {        // 彩色图像处理(逐通道)        vector<Mat> channels;        split(src, channels);        vector<Mat> resultChannels(3);        for (int i = 0; i < 3; ++i) {            resultChannels[i] = homomorphicFilter(channels[i], 1.5f, 0.5f, 1.0f, 30.0f);        }        merge(resultChannels, result);    } else {        cout << "不支持的图像通道数" << endl;        return -1;    }    imshow("src", src);    imshow("result", result);    waitKey(0);    return 0;}

4. 总结

同态滤波是一种通过频域处理解决图像光照不均的关键技术,其作用在于分离并差异化调整图像的低频光照分量和高频反射分量,增强图像对比度和细节,从而提高图像的视觉质量和可分析性。这在光照条件复杂或需要突出局部特征的应用中具有重要意义。

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

同态滤波 图像增强 OpenCV C++ 高斯滤波器
相关文章