2013-03-11 3 views
7

OpenCV関数cvtColorは、マトリックスの色空間をRGBからグレースケールに変換します。関数のC++署名がOpenCV関数cvtColorを使用して行列を変換できますか?

void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0) 

この関数はsrcdstと同じ目的で、すなわち、所定の位置にマトリックス変換に使用することができますか?

cv::Mat mat = getColorImage(); 
cvtColor(mat, mat, CV_RGB2GRAY); 

(私は先がソースよりも異なる数のチャネルを持っているとして、いずれかの方法は、それはまだ先のためにメモリの新しいブロックを割り当てる必要があることに注意してくださいね。)

詳細一般的に、OpenCV APIには、このようにして関数をいつ使用するかを決める慣習がありますか?

+1

ソースと宛先のチャネル数が同じ場合に実行できます。例えばRGBからYUV、RGBからYCbCr、またはその逆など... – sgarizvi

答えて

3

答えが遅すぎるかもしれませんが、私はここに書かれたいくつかのことに同意しないと言いたいと思います。
宛先マトリックスが「チャンネル数が同じ」でない場合、または宛先マトリックスがまだ作成されていない場合でも、ソースと宛先と同じ正確なMatを問題なく配置できます。
OpenCVのプログラマが徹底的に設計しました。
この関数のすべてのユーザーは、ソースのMatが正しいこと、チャンネルの数とデータの種類に注意し、関数呼び出しの後に変更できることに注意してください。

証明が

Mat src = _src.getMat(); 

はマットdstが作成され、その後、呼ばれ、ライン2406、cv::cvtColor(…)関数内だけで最初の行に、source codeを見てから来ている(とdst = _dst = _scr)。
したがって、cv::cvtColor(…)内の状況は、インプレースコールを行うときに次のようになります。srcは古いマトリックスを指します。_src、_dst、dstはすべて、同じ新しい割り当て済みマトリックスを指します。
これは、新しい変数srcおよびdst(関数呼び出し_srcおよび_dstからのものではない)が実際の変換関数に渡す準備ができていることを意味します。
関数void cv::cvtColor(…)が実行されると、srcが破棄され、_src、_dst、およびdstはすべて同じMatを指し、_dstのrefcountは1になります。

+0

はい現時点で実際にテストする時間はありませんが、これに同意します。しかし、私が見ることができるように、InputArrayを渡すことは、cv :: Matで値渡しすることと同じです。つまり、2つの行列が同じデータセットを指しています。再割り当てが必要な場合、元のデータを指す元の行列ヘッダーには影響しません。 –

+0

はい、再割り当て後、新しいマトリックスはデスティネーションマットになりますが、ソースマットは一時的であり、機能が終了すると失われます。私はちょうどそれをテストしたし、このインプレーススキームはOpenCvフレームワークで普通の(ほぼ標準的な)ようだ。 –

3

コードhereを見ると、行番号2420のにcreateが呼び出されます。つまり、このセクションのデータセクションとヘッダーが書き換えられます。だから、srcdstの同じ行列でこの関数を呼び出すことはお勧めできません。

OpenCVでの慣例として、InputArray and OutputArrayを見てください。これらは、入出力のデータ型として関数呼び出しが存在するときはいつも、異なるMat変数を使用するべきであることを示唆しているようです。

+0

うーん、私はあなたが意味するものを参照してください。しかし、行列がInputArrayに変換されたときに新しいヘッダを受け取る場合がありますか?新しいヘッダを提供するために、ポインタを使用します。また、_InputArrayのヘッダーを見ると、getMat()関数はMatを返すことも示唆しています(https://github.com/Itseez/opencv/blob/9b7dfd677db5818b8dd699e2059c886a1e7ce24f/modules/core/include/opencv2/core/core.hpp)同じヘッダーデータへの参照ではなく、独自のヘッダーを使用します。 –

+0

はい...正確には...おそらく異なるMat変数を使用するべきでしょう。これらのアプリケーションをデバッグするには、ヘッダーの変更先とデータの明確なアイデアがなければ少し難しいかもしれません。 – subzero

2

は、cv::cvtColorの呼び出し後に正しく変換された行列を含むという意味でインプレースで動作する必要があります。しかし、入力チャンネル数が出力チャンネル数と異なる場合は、マトリックスのデータが再割り当てされます。

あなたはcvtColorへのインプレース呼び出し後にdstが正しく変換された画像を持っていないサンプルを持っている場合は、http://code.opencv.org

上のバグとしてそれを提出してくださいより一般的には、OpenCVのAPI内の慣例がありますこのようにしていつ機能が使用されるかを判断するには?

このような規則はありません。しかし、基本的な画像処理機能の大半はインプレースで動作することが期待できます。したがって、すべての変換、フィルタ、しきい値、アフィン/パースペクティブ変換は、インプレースコールをサポートすることが知られています。

関連する問題