OpenCV图像滤波(13)均值迁移滤波函数pyrMeanShiftFiltering()的使用

发布于:2024-08-17 ⋅ 阅读:(65) ⋅ 点赞:(0)
  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

算法描述

函数执行均值迁移图像分割的初始步骤。
该函数实现了均值迁移分割的过滤阶段,即输出是经过滤波的“海报化”图像,其中颜色梯度和平滑纹理已被平坦化。对于输入图像(或缩小的输入图像,见下文)的每一个像素 (X,Y),函数都会执行均值迁移迭代,也就是说,在联合空间-色彩超空间中考虑像素 (X,Y) 的邻域:
( x , y ) : X − sp ≤ x ≤ X + sp , Y − sp ≤ y ≤ Y + sp , ∣ ∣ ( R , G , B ) − ( r , g , b ) ∣ ∣ ≤ sr (x,y): X- \texttt{sp} \le x \le X+ \texttt{sp} , Y- \texttt{sp} \le y \le Y+ \texttt{sp} , ||(R,G,B)-(r,g,b)|| \le \texttt{sr} (x,y):XspxX+sp,YspyY+sp,∣∣(R,G,B)(r,g,b)∣∣sr
其中 (R,G,B) 和 (r,g,b) 分别是在 (X,Y) 和 (x,y) 上的颜色分量向量(尽管算法并不依赖于所使用的颜色空间,因此任何 3 组件颜色空间都可以使用)。在邻域内找到平均空间值 (X’,Y’) 和平均颜色向量 (R’,G’,B’),它们作为下一次迭代的邻域中心:
( X , Y )   ( X ′ , Y ′ ) , ( R , G , B )   ( R ′ , G ′ , B ′ ) . (X,Y)~(X',Y'), (R,G,B)~(R',G',B'). (X,Y) (X,Y),(R,G,B) (R,G,B).
迭代完成后,初始像素(即迭代开始的像素)的颜色分量设置为最终值(最后一次迭代的平均颜色):
I ( X , Y ) < − ( R ∗ , G ∗ , B ∗ ) I(X,Y) <- (R*,G*,B*) I(X,Y)<(R,G,B)
当 maxLevel > 0 时,构建高斯金字塔,包含 maxLevel+1 层,并首先在最小层上运行上述过程。之后,结果传播到较大的层,并且仅在金字塔较低分辨率层的颜色与当前层的颜色相差超过 sr 的像素上再次运行迭代。这使得颜色区域的边界更加清晰。需要注意的是,结果实际上与在整个原始图像上运行均值迁移程序(即 maxLevel==0)的结果不同。

pyrMeanShiftFiltering 是 OpenCV 中的一个函数,用于实现均值迁移滤波(Mean Shift Filtering)。这是一种非局部均值滤波技术,可以用于图像分割、降噪等多种图像处理任务。

函数原型

void cv::pyrMeanShiftFiltering
(
	InputArray 	src,
	OutputArray 	dst,
	double 	sp,
	double 	sr,
	int 	maxLevel = 1,
	TermCriteria 	termcrit = TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 5, 1) 
)		

参数

  • 参数src 源图像,8 位、3 通道。
  • 参数dst 目标图像,与源图像格式和大小相同。
  • 参数sp 空间窗口半径。
  • 参数sr 颜色窗口半径。
  • 参数maxLevel 用于分割的最大金字塔层级。
  • 参数termcrit 终止准则:何时停止均值迁移迭代。

代码示例


#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // 加载图像
    cv::Mat img = cv::imread("/media/dingxin/data/study/OpenCV/sources/images/erik.jpg", cv::IMREAD_COLOR);

    if (img.empty()) {
        std::cout << "无法加载图像,请检查路径是否正确。" << std::endl;
        return -1;
    }

    cv::Size sz2Sh( 400, 600 );
    cv::resize( img, img, sz2Sh, 0, 0, cv::INTER_LINEAR_EXACT );

    // 使用 pyrMeanShiftFiltering 对图像进行滤波
    cv::Mat filtered_img;
    double spatial_radius = 10; // 空间窗口半径
    double color_radius = 20;   // 颜色窗口半径
    int max_level = 1;          // 最大金字塔层级
    cv::TermCriteria term_crit(cv::TermCriteria::MAX_ITER+cv::TermCriteria::EPS, 5, 1); // 终止准则
    cv::pyrMeanShiftFiltering(img, filtered_img, spatial_radius, color_radius, max_level, term_crit);

    // 显示结果
    cv::namedWindow("Original Image", cv::WINDOW_NORMAL);
    cv::imshow("Original Image", img);

    cv::namedWindow("Filtered Image", cv::WINDOW_NORMAL);
    cv::imshow("Filtered Image", filtered_img);

    cv::waitKey(0); // 等待按键

    return 0;
}

运行结果

在这里插入图片描述