13

OpenCV関数cvtColorは、マトリックスの色空間を変換します(たとえば、RGBからグレースケールに)。関数のC++シグネチャは

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

この関数を使用して、行列を所定の位置に変換できますか?つまりsrc、同じオブジェクトを使用できますdstか?

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

(どちらの方法でも、宛先には送信元とは異なるチャネル数があるため、宛先に新しいメモリブロックを割り当てる必要があることを認識しています。)

より一般的には、OpenCV API内に、関数をこのように使用できる時期を決定するための規則がありますか?

4

3 に答える 3

10

答えるには遅すぎるかもしれませんが、ここに書かれていることに同意できないと言いたいです。
宛先マトリックスに「同じ数のチャネル」がない場合、または宛先マトリックスがまだ作成されていない場合でも、ソースおよび宛先とまったく同じマットを問題なく配置できます。
OpenCVプログラマーはそれを徹底的に設計しました。
この関数のすべてのユーザーは、チャネルの数とデータのタイプに関してソースマットが正しいことを確認し、関数の呼び出し後に変更される可能性があることを覚えておく必要があります。

証明は、関数内の最初の行である2406行目のソースコードを確認することで得られます。cv::cvtColor(…)

Mat src = _src.getMat();

が呼び出されると、Mat dstが作成されます(およびdst = _dst = _scr)。
したがって、cv::cvtColor(…)インプレース呼び出しを行う場合の内部の状況は次のとおりです。srcは古いマトリックスを指し、_src、_dst、dstはすべて、宛先マトリックスとなる同じ新しい割り当てられたマトリックスを指します。
これは、新しい変数srcおよびdst(関数呼び出し_srcおよび_dstからのものではない)が実際の変換関数に渡される準備ができていることを意味します。
関数void cv::cvtColor(…)が実行されると、srcは破棄され、_src、_dst、およびdstはすべて同じマットを指し、_dstのrefcountは1になります。

于 2016-01-03T09:45:26.150 に答える
3

ここのコードを見ると、2420行目でacreateが行列で呼び出されていることがわかりますdst。これは、このマトリックスのデータセクションとヘッダーが書き換えられることを意味します。srcしたがって、とで同じ行列を使用してこの関数を呼び出すことはお勧めできませんdst

OpenCVの規則については、InputArrayとOutputArrayを見てください。これらは、入力と出力のデータ型としてこれらを使用する関数呼び出しが存在する場合は常に、おそらく異なるMat変数を使用する必要があることを示唆しているようです。

于 2013-03-11T18:12:25.200 に答える
2

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

dstインプレース呼び出し後に画像が正しく変換されていないサンプルがある場合は、http://code.opencv.orgcvtColorでバグとして送信してください。

より一般的には、OpenCV API内に、関数をこのように使用できる時期を決定するための規則がありますか?

そのような慣習はありません。ただし、基本的な画像処理機能のほとんどはインプレースで機能することが期待できます。したがって、すべての変換、フィルター、しきい値、アフィン/パースペクティブ変換は、インプレース呼び出しをサポートすることがわかっています。

于 2013-03-11T20:58:01.427 に答える