c++ - 如何使用 Matlab 函数 ordfilt2 到 C++ 和 OpenCV

标签 c++ matlab opencv image-processing

我需要使用 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 表示顺序统计过滤器。但是当我在网上寻找它时,似乎找不到任何有用的东西。到目前为止,我所有的尝试都失败了,所以,你能帮帮我吗?

非常感谢您的帮助。

最佳答案

你关心的代码在这里:

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

您是正确的,因为它是一个订单统计过滤器。它专门采用滑动邻域并输出所需的窗口等级。您已将其设置为 3 x 3 邻域,第一行输出等级 9,或最高等级或最高值。这是局部最大值,您可以通过使用形态学运算的扩张运算符来实现这一点。同样,下一行输出最低等级,等级 1 或最低值。这是局部最小值,您可以使用形态学操作通过侵 eclipse 操作来实现。

您首先需要使用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::dilatecv::erode 需要structuring element 来操作第三个参数。不可否认,您可以将 Mat() 指定为第三个元素,默认情况下它将使用 3 x 3 邻域进行操作。

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

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

关于c++ - 如何使用 Matlab 函数 ordfilt2 到 C++ 和 OpenCV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43098658/

相关文章:

javascript - 浏览器能否将有效负载数据拆分为多个 websocket 帧?

c++ - VTK dyld : Library not loaded: libvtkDomainsChemistryOpenGL2-7. 1.1.dylib

matlab - 如何从黑白图片中提取车牌

matlab - 为什么 MATLAB save() 调用 saveobj() 两次?

opencv - JavaCV中的缝合器

c++ - 静态库接口(interface)中未公开的类的名称冲突 (c++)

c++ - Arduino:显示的自定义类不起作用;没有编译器错误

android - 在平面图图像上显示路线

opencv - opencv已触发为RtlValidateHeap指定的断点无效地址

带有opencv异常的c++动态分配