【问题标题】:How to use Matlab function ordfilt2 to C++ with OpenCV如何在 OpenCV 中使用 Matlab 函数 ordfilt2 到 C++
【发布时间】:2023-03-22 21:22:01
【问题描述】:

我需要使用 Matlab ordfilt2 的功能来过滤噪声图像。

我的代码示例:

#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
#include <opencv/cv.h>
#include <iostream>
#include <Windows.h>

using namespace std;
using namespace cv;

int main(int, char**)
{
Mat image = imread("C:\lena.bmp", 0);
Mat result = image.clone();
Mat final2 = image.clone();

if (image.empty())//check if empty
{
    printf("Image is not read! File is probably missing! Press any key to exim program");//message for error
    Sleep(10000); //10 second delay for showing message to user
}
else
{
    double value = 0.3;

    //printf("Give double for noise [0.00-1.00] :\n");
    //cin >> value;

    if (value >= 0.00 && value <= 1.00)
    {
        // imGray is the grayscale of the input image
        Mat noise = Mat(image.size(), CV_64F);
        normalize(image, result, 0.0, 1.0, CV_MINMAX, CV_64F);
        randn(noise, 0, value);

        result = result + noise;
        normalize(result, result, 0.0, 1.0, CV_MINMAX, CV_64F);
        imshow("Output image with noise", result);
        // I found this function (from OpenCV documentation) but I get syntax error
        dilate(result, final2, NULL, 1);

        namedWindow("Image blur", 1);
        imshow("Image blur", result);

        namedWindow("Original Image", 1);
        imshow("Original Image", image);

        waitKey();
    }
    else
    {
        printf("Wrong input! Try again!\n");
    }
}
return 0;
}

编辑 Matlab 代码:

x=imread('cameraman.tif');
x=Im2double(x);
sigma=20;
y=x+sigma*rabdn(size(x))/255;
z1=ordfilt2(y,3*3,ones(3,3));
z2=ordfilt2(y,1,ones(3,3));
z=1/2*(z1*z2);
Imshow(y,());
figure; Imshow (z1,());
figure; Imshow (z2,());
figure; Imshow (z,());

我尝试过使用扩张功能,但没有运气。

我认为 ordfilt2 表示订单统计过滤器。但是当我在网上寻找它时,我似乎找不到任何有用的东西。到目前为止,我所有的尝试都失败了,所以,你能帮帮我吗?

非常感谢您的帮助。

【问题讨论】:

  • 请提供您如何在 MATLAB 中使用 ordfilt2。您尚未指定使用的顺序以及窗口的大小,但您是正确的。这是一个订单统计过滤器。它对所有值进行排序,并使用指定的排名,输出该排名的值。从最小值 1 到最大值 M,其中 M 是邻域的大小。根据您使用的排名,这将告诉我们如何替换该调用。
  • 您好,感谢您的回复,我想使用该功能以特定方式过滤我的噪声图像。在 Matlab 中,我们使用了 ordfilt2,但是对于 OpenCV 和 C++,我似乎无法弄清楚如何做完全相同的事情。你有什么想法吗?
  • 你还没有回答我的问题。你打电话给ordfilt2的确切方式是什么? OpenCV 中没有等效的功能,但如果您告诉我您使用 ordfilt2 使用的等级,我可以告诉您可以使用哪个形态运算符......所以请回答我的问题。
  • 如果 OP 从 here 中读取 ordfilt2 的工作原理,他可以确定在 OpenCV 中使用哪个过滤器。
  • @rayryeng 我编辑了我的帖子并包含了我拥有的 Matlab 代码,我需要使用 C++ 和 OpenCV 做完全相同的事情。

标签: c++ matlab opencv image-processing


【解决方案1】:

你关心的代码在这里:

z1=ordfilt2(y,3*3,ones(3,3));
z2=ordfilt2(y,1,ones(3,3));

您是正确的,因为它是一个订单统计过滤器。它专门采用滑动邻域并输出所需的窗口rank。您已将其设置为 3 x 3 邻域,第一行输出排名 9,或最高排名或最高值。这是局部最大值,您可以通过使用形态学运算的膨胀运算符来完成此操作。类似地,下一行输出最低等级、等级 1 或最小值。这是局部最小值,您可以使用形态学操作通过侵蚀操作来完成此操作。

您首先需要使用cv::getStructuringElement 创建您要操作的窗口。你基本上想要一个 3 x 3 的正方形,所以你会使用 MORPH_RECT 属性。然后您将分别使用cv::dilate,然后是cv::erode。

因此,将您当前的 dilate 行代码替换为:

//...
imshow("Output image with noise", result);

Mat se = getStructuringElement(MORPH_RECT, Size(3, 3));
dilate(result, final2, se);
erode(final2, final2, se);

//...

cv::dilate 和 cv::erode 需要 结构元素 对第三个参数进行操作。诚然,您可以指定 Mat() 作为第三个元素,默认情况下将使用 3 x 3 邻域进行操作。

您还需要更改 imshow 命令以显示最终图像,而不是中间图像:

namedWindow("Image blur", 1);
imshow("Image blur", final2); // Change here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-28
    • 2015-03-09
    • 1970-01-01
    • 2015-12-08
    • 2013-07-13
    • 1970-01-01
    • 2013-02-03
    • 2018-10-03
    相关资源
    最近更新 更多