Frangi 滤波 学习记录
Frangi 滤波,它是图像处理里经典的 线状/管状结构增强滤波器(vesselness filter),最初用于血管/管道检测,但在工业检测、纹理分析、缺陷检测也很常用。下面我帮你系统梳理一下。
1️⃣ Frangi 滤波器的核心思想
Frangi 滤波器基于 Hessian 矩阵的特征值分析,判断图像局部结构类型:
- 输入:灰度图像 I(x,y)I(x, y)I(x,y)
- 计算局部 Hessian 矩阵:
H(x,y)=[IxxIxyIxyIyy]H(x,y) = \begin{bmatrix} I_{xx} & I_{xy} \\ I_{xy} & I_{yy} \end{bmatrix}H(x,y)=[IxxIxyIxyIyy]
- 求特征值 λ1,λ2\lambda_1, \lambda_2λ1,λ2(假设 ∣λ1∣≤∣λ2∣|\lambda_1| \le |\lambda_2|∣λ1∣≤∣λ2∣)
- 构建 vesselness 响应:
V0={0,λ2>0exp(−RB22β2)(1−exp(−S22c2)),elseV_0 = \begin{cases} 0, & \lambda_2 > 0 \\ \exp\Big(-\frac{R_B^2}{2\beta^2}\Big)\big(1 - \exp(-\frac{S^2}{2c^2})\big), & \text{else} \end{cases}V0={0,exp(−2β2RB2)(1−exp(−2c2S2)),λ2>0else
其中:
- RB=∣λ1∣/∣λ2∣R_B = |\lambda_1| / |\lambda_2|RB=∣λ1∣/∣λ2∣ → 衡量“线状 vs 区域”
- S=λ12+λ22S = \sqrt{\lambda_1^2 + \lambda_2^2}S=λ12+λ22 → 测量“结构强度”
- β,c\beta, cβ,c → 控制灵敏度
2️⃣ 多尺度处理
- 血管/纹理可能不同粗细
- 对不同 σ\sigmaσ 进行 Gaussian 平滑,计算 Hessian
- 最终取最大响应:
V(x,y)=maxσ∈[σmin,σmax]Vσ(x,y)V(x,y) = \max_{\sigma \in [\sigma_\text{min}, \sigma_\text{max}]} V_\sigma(x,y)V(x,y)=σ∈[σmin,σmax]maxVσ(x,y)
3️⃣ OpenCV / C++ 实现思路
OpenCV 没有内置 Frangi,但可以用 Hessian + 特征值自己实现:
#include <opencv2/opencv.hpp>
using namespace cv;
Mat frangi2D(const Mat &src, float sigma = 1.0f)
{
Mat img;
src.convertTo(img, CV_32F, 1.0/255.0);
// 高斯平滑
GaussianBlur(img, img, Size(0,0), sigma, sigma);
// 计算二阶导数
Mat Ixx, Iyy, Ixy;
Sobel(img, Ixx, CV_32F, 2, 0, 3);
Sobel(img, Iyy, CV_32F, 0, 2, 3);
Sobel(img, Ixy, CV_32F, 1, 1, 3);
Mat vesselness = Mat::zeros(img.size(), CV_32F);
for(int y=0; y<img.rows; y++)
{
for(int x=0; x<img.cols; x++)
{
float a = Ixx.at<float>(y,x);
float b = Ixy.at<float>(y,x);
float c = Iyy.at<float>(y,x);
// Hessian 特征值
float trace = a + c;
float det = a*c - b*b;
float lambda1 = trace/2 + sqrt(trace*trace/4 - det);
float lambda2 = trace/2 - sqrt(trace*trace/4 - det);
// |λ1| ≤ |λ2|
if (abs(lambda1) > abs(lambda2)) std::swap(lambda1, lambda2);
// vesselness
float beta = 0.5f;
float cval = 15.0f;
float Rb = abs(lambda1)/abs(lambda2);
float S = sqrt(lambda1*lambda1 + lambda2*lambda2);
float V = exp(-Rb*Rb/(2*beta*beta)) * (1 - exp(-S*S/(2*cval*cval)));
if(lambda2 > 0) V = 0;
vesselness.at<float>(y,x) = V;
}
}
return vesselness;
}
- 可扩展成 多尺度,取最大响应
- 输出
vesselness map→ 可用于 阈值分割 / 缺陷检测 / 线结构增强
4️⃣ Frangi 滤波器常用参数(推荐参考值)
| 参数 | 建议值 | 说明 |
|---|---|---|
| σ (sigma) | 1~5 | 高斯平滑尺度,检测不同宽度纹理 |
| β | 0.5~1 | 控制线状结构敏感度 |
| c | 15~30 | 抑制噪声影响 |
| threshold | 0.2~0.5 | 对 vesselness map 二值化 |
5️⃣ 使用场景
- 医学图像:血管检测
- 工业检测:铝箔折痕、划痕、PCB 线路、纤维纹理
- 遥感图像:河流、道路增强
- AR/VR 算法:结构纹理增强,后续几何校正或匹配
更多推荐
所有评论(0)