4

画像内の赤いレーザー ラインを検出する必要があるプロジェクトに取り組んでいます。これが私が考えている戦略です。

  1. 画像の R、G、B チャンネルを分離します。
  2. 高い強度値で画像のしきい値を設定します。
  3. 生成された 3 つのバイナリ イメージを使用して、要素単位の操作 r && !g && !b を実行します。(&& は論理 AND、! は論理 NOT です)。
  4. 結果のマトリックスは、レーザーが存在した領域に 1 を含むバイナリ イメージです。

これは、Matlab のいくつかのテスト画像で機能しました。しかし、私の問題は、C/C++ で OpenCV を使用してこれを実装する必要があることです。

ほとんどのライブラリ関数を試してみましたが、バイナリ イメージを操作して論理演算を実行する直感的で簡単な方法はないようです。

誰かが私が役に立つと思うOpenCV関数/メソッドを教えてもらえますか? しきい値処理に使用できると考えましたcvThresholdImageが、それはほとんどそれです。

4

1 に答える 1

3

それで、あなたはすでにopenCVのステップ1と2を理解しましたか?論理演算子を使用しようとしているだけの場合、openCVを使用すると、論理演算子を使用して操作できる生データにアクセスできます。すでに3つのチャネルに分割され、しきい値処理されていると仮定します

//three binary images in the format you specified above
cv::Mat g;
cv::Mat b;
cv::Mat r;
uchar* gptr = g.data();
uchar* bptr = b.data();
uchar* rptr = r.data();

//assuming the matrix data is continuous you can just iterate straight through the data
if(g.isContinuous()&&r.isContinuous()&&b.isContinuous())
{  
  for(int i = 0; i < g.rows*g.cols; i++)
  {
     rptr[i] = rptr[i]&&!bptr[i]&&!gptr[i];
  }
}

rには、説明した出力が含まれています。rを上書きしたくない場合は、それを新しい行列にコピーすることもできます。

cv :: Matを反復処理してすべてのデータポイントにアクセスするには、いくつかの方法があります。C++は、必要なすべての論理演算子を提供します。私の知る限り、openCVは行列論理演算子関数を提供していませんが、上記のように非常に簡単に独自の演算子を記述できます。

編集 QuentinGeissmannによって提案されたように、bitwise_not関数とbitwise_and関数を使用して同じことを実行できます。私はそれらが存在することに気づいていませんでした。データを反復処理する必要がある回数が多いため、それらの使用は遅くなると思いますが、より少ないコードで実行できます。

cv::bitwise_not(g,g);
cv::bitwise_not(b,b);
cv::bitwise_and(b,g,b);
cv::bitwise_and(r,b,r);
//r now contains r&&!b&&!g
于 2012-08-15T19:25:58.907 に答える