2017-03-29 13 views
1

ノイズのある画像をフィルタリングするには、Matlab ordfilt2関数を使用する必要があります。私のコードのMatlab関数ordfilt2をOpenCVでC++に変換する方法

例:

#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; 
} 

EDIT 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は順序統計フィルタを意味すると思います。しかし、私がウェブ上でそれを探すと、役に立たないものは見つけられないようです。私のすべての試みはこれまで失敗しているので、私を助けてくれますか?

ご協力いただきありがとうございます。

+0

あなたはMATLABで 'ordfilt2'を使用しているどのようにしてください。使用しているオーダーとウィンドウのサイズは指定されていませんが、正しいです。注文統計フィルタです。それはすべての値をソートし、指定されたランクでそのランクの値を出力します。最小値である1から、Mが近傍のサイズである最大値である「M」に始まる。使用しているランクに応じて、その通話をどのように置き換えることができるかがわかります。 – rayryeng

+0

こんにちは、ご返信ありがとうございます。 この機能を使用して、ノイズの多い画像を特定の方法でフィルタリングしたいと考えています。 Matlabではordfilt2を使用しましたが、OpenCVとC++ではまったく同じことをする方法がわかりません。あなたはなにか考えはありますか? – adamkwn

+0

あなたはまだ私の質問に答えていません。あなたが 'ordfilt2'と呼んでいる正確な方法は何ですか? OpenCVには同等の機能はありませんが、 'ordfilt2'でどのランクを使用しているのかを教えてもらえれば、どのモルフォロジー演算子を使うことができるのかを知ることができます。 – rayryeng

答えて

0

あなたが心配しているコードはここにある:それは順序統計フィルタであるという点で

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

あなたは正しいです。具体的には、スライディング近傍をとり、ウィンドウの所望のランクを出力する。あなたはこれを3 x 3近傍に設定し、最初の行はランク9、または最高ランクまたは最高値を出力します。これはローカル最大であり、形態演算を使用して拡張演算子でこれを行うことができます。同様に、次の行は、最低ランク、ランク1または最低値を出力します。これはローカルのであり、形態学的操作を使用した侵食操作でこれを達成できます。

まず、操作するウィンドウを作成するには、cv::getStructuringElementを使用する必要があります。基本的に3×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は三番目のパラメータのために動作するよう構造要素が必要です。確かに、Mat()を3番目の要素として指定することができます。この要素は、デフォルトで3 x 3近傍を使用して動作します。

また、最終的なイメージではなく、中間のものを表示するようにimshowコマンドを変更したいと思う:

namedWindow("Image blur", 1); 
imshow("Image blur", final2); // Change here 
関連する問題