1

HSV 色空間で 3 チャネルのマ​​トリックスを反復処理する必要がありますが、非常に遅いです。約2.5秒かかります。

cv::Mat img = cv::imread( "image.jpg" );
cv::Mat img32FC3;

img.convertTo( img32FC3, CV_32FC3 );
cv::cvtColor( img32FC3, img32FC3, CV_BGR2HSV );
int height = img32FC3.rows;
int width = img32FC3.cols;
cv::Size size = img32FC3.size();
if( img32FC3.isContinuous() ) {
  size.width *= size.height;
  size.height = 1;
}
size.width *= 3;
for( int i = 0; i < size.height; i ++ ) {
    float* ptr = img32FC3.ptr<float>(i);

    for( int j = 0; j < size.width; j += 3 ) {
        h = (ptr[ j ]);
        s = (ptr[j +1 ]);
        v = (ptr[j +2 ]);
    }
}

cv::cvtColor( img32FC3, img32FC3, CV_HSV2BGR );
img32FC3.convertTo( img, CV_8UC3 );
imwrite("test.jpg", img );

上記のコードは、openCV のドキュメントから改作されており、パフォーマンスが優れていると記載されています。2.5秒は本当に非常に遅いので、どうすればこれをスピードアップできるのでしょうか:(。

ところで: 画像は 3744x5616 ピクセルです

4

2 に答える 2

3

マットのデータは期待どおりに保存されないことがあるため、直接アクセスしないでください。ここで私の答えを確認してください。

もう 1 つの方法は、Mat イテレータを使用することです。[opencv_tutorials.pdf、ver 2.4.2 pp. 89-92] によると、私のリンクのネストされたループよりもわずかに遅いです。(大きな画像の場合、5% 遅くなりますが、適切なコンパイラによってさらに最適化できるconstではなく、MatIterator のみを使用したことに注意してください。)

MatConstIterator_<Vec3b> it = M.begin<Vec3b>(), it_end = M.end<Vec3b>();
for(; it != it_end; ++it)
{ 
  //do sth read-only otherwise use MatIterator_<Vec3b>
  b = (*it)[0]; 
  g = (*it)[1]; 
  r = (*it)[2]; 
}

<double>グレースケールの場合、ocv2.4.2 refman p19 から。

于 2012-11-07T02:28:33.180 に答える
1

高速化する最善の方法は、ループを並列化することです。OpenCV はマルチスレッド環境として TBB を使用しています。確認してみてください。ところで、サイズなどに関するすべての計算を行う必要はありません。行列 isContinuous() を既に確認しているのでfloat ptr = reinterpret_cast<float>(img32FC3.data)、ループとしてポインターを取得できます。

for (size_t i = ; i < img32FC3.rows*img32FC3.cols; ++i, ptr +=3) {
  // do something
}
于 2012-10-15T07:51:54.033 に答える