1

深度とチャンネル番号が不明な画像を読み取った後、そのピクセルに 1 つずつアクセスしたいと考えています。

opencv 1.x では、コードは次のようになります。

IplImage * I = cvLoadImage( "myimage.tif" );
CvScalar pixel = cvGet2D( I, y, x );

しかしopencv 2.xでは、cv::Mat.at()メソッドは画像のタイプを知っていることを要求します:

cv::Mat I = cv::imread( "myimage.tif" );
if( I.depth() == CV_8U && I.channels() == 3 )
    cv::Vec3b pixel = I.at<cv::Vec3b>( x, y );
else if( I.depth() == CV_32F && I.channels() == 1 )
    float pixel = I.at<cv::float>( x, y );

コンパイル時に画像の型を知らなくてcvGet2Dも受け取っcv::Matて返すことができるような関数はありますか?cv::Scalar

4

4 に答える 4

1

短い答えはノーです。C++ API にはそのような関数はありません。

この背後にある理論的根拠はパフォーマンスです。cv::Scalar(およびCvScalar) は と同じですcv::Vec<double,4>。したがって、Mat以外の型の場合CV_64FC4、 を取得するには変換が必要cv::Scalarです。switchさらに、このメソッドは、あなたの例のように巨人になります(ブランチは2つしかありません)。

しかし、この機能は便利な場合が多いと思います。私の推測では、人々はそれを過度に使用する傾向があり、その結果、アルゴリズムのパフォーマンスが非常に低下する. したがって、OpenCV は、クライアント コードが静的に型付けされたメソッドを使用するように強制するために、個々のピクセルへのアクセスを少し不便にします。多くの場合、実際には型を静的に知っており、パフォーマンスに関しては非常に重要であるため、これは便利な点ではそれほど大したことではありません。したがって、私はそれを良いトレードオフだと考えています。

于 2013-10-22T08:14:10.937 に答える