2017-01-30 11 views
2

私は、C++のfilter2DのOpenCV実装と、対応するカーネルの直接実装の違いに気付きました。その質問の著者はfilter2D機能の作業実装を取得しようとしたfilter2D OpenCV関数C++

Opencv - how does the filter2D() method actually work?

:私は、次の質問を読みました。彼は、フィルタの正規化バージョンを使用すると正しい結果が得られると主張しています。私は彼の仮説をテストし、すべての係数が正の場合にのみ正規化が正解を与えることを見出した。したがって、平均化フィルタはfilter2D関数を使ってうまく実装することができます[カーネルを正規化しなければなりません]。

しかし、これは、Sobel、Laplacian、エッジ検出フィルタなどの負の係数を持つフィルタでは当てはまりません。その質問の著者は私と同じ問題に遭遇しました。

https://stackoverflow.com/users/2669614/bovaz

上記の利用者は、リンクされた質問に答えました。彼は、カーネルの係数の合計がゼロに等しい場合、filter2Dはその実装を変更する可能性があると主張しました。それは事実ですか? C +でfilter2Dを実装すると、直接実装とは異なる結果が得られるのはなぜですか?私は、filter2DをPythonでチェックし、対応するカーネルをC++で直接実装すると、同じ結果が得られます。

答えて

0

主にスケーリングやオーバーフローの問題が原因です。 filter2Dのドキュメントには、オーバーフローした値が切り捨てられているか、またはmin-maxの範囲に適切にスケーリングされているかどうかはわかりません(少なくとも私は見つかりませんでした)。 これは、方向性フィルタの場合、係数が正と負、代数の後でより重要になります 上記のリンクに表示されている関数 'myfilter2D'は、最小の範囲。

サンプルコードを投稿することができれば、助けが簡単になります。

私は、行列を浮動小数点に変換して代数演算を行うことをお勧めします。これは結果の値を保持する傾向があり、オーバーフローや彩度のために値が失われないためです。 im2double() - > "代数演算を実行する" - >表示するim2uchar()

void im2uchar(Mat & src, Mat & dest){ 
    double minVal, maxVal; 
    minMaxLoc(src, &minVal, &maxVal); //find minimum and maximum intensities 
    src.convertTo(dest, CV_8U, 255.0/(maxVal - minVal), -minVal * 255.0/(maxVal - minVal)); 
    } 

void im2float(Mat & src, Mat & dest){ 
    double minVal, maxVal; 
    minMaxLoc(src, &minVal, &maxVal); //find minimum and maximum intensities 
    src.convertTo(dest, CV_32F, 1.0/(maxVal - minVal), -minVal * 1.0/(maxVal - minVal)); 
    } 
関連する問題