OpenCV を使用して、ビデオ ストリーム内の赤いピクセルのしきい値を設定しようとしています。他の色も問題なく機能していますが、赤は色相軸を包み込むため問題を引き起こします (つまり、HSV(0, 255, 255) と HSV(179, 255, 255) は両方とも赤です)。私が現在使用している手法は理想的とは言えません。基本的:
cvInRangeS(src, cvScalar(0, 135, 135), cvScalar(20, 255, 255), dstA);
cvInRangeS(src, cvScalar(159, 135, 135), cvScalar(179, 255, 255), dstB);
cvOr(dstA, dstB, dst);
青の簡単なケースと比較すると、赤 (潜在的なバグ) のコードの分岐、2 つの余分な画像の割り当て、および 2 つの追加の操作が必要になるため、これは最適ではありません。
cvInRangeS(src, cvScalar(100, 135, 135), cvScalar(140, 255, 255), dst);
私が思いついたより良い代替案は、画像の色を「回転」して、ターゲットの色相が 90 度になるようにすることでした。例えば。
int rotation = 90 - 179; // 179 = red
cvAddS(src, cvScalar(rotation, 0, 0), dst1);
cvInRangeS(dst1, cvScalar(70, 135, 135), cvScalar(110, 255, 255), dst);
これにより、すべての色を同じように扱うことができます。
ただし、cvAddS
色相値が 0 を下回った場合、この操作では色相値が 180 に戻されないため、データが失われます。CvMat
画像から減算し、モジュラスを使用して負の値を範囲の一番上にラップできるように画像を変換することを検討しましたが、CvMat
モジュラスをサポートしていないようです。もちろん、すべてのピクセルを反復処理することもできますが、非常に遅くなることが懸念されます。
私は多くのチュートリアルとコードサンプルを読みましたが、それらはすべて、色相スペクトルをラップしない範囲のみを便利に見ているか、さらに醜いソリューションを使用しているようです (たとえばcvInRangeS
、すべてのピクセルを反復して再実装し、カラー テーブルとの手動比較)。
それで、これを解決する通常の方法は何ですか?最善の方法は何ですか?それぞれのトレードオフは何ですか?組み込みの CV 関数を使用するよりも、ピクセルの反復処理がはるかに遅くなりますか?