2017-03-02 5 views
0

私はドレスの支配的な色を見つけようとしています。OpenCV:カラーカスターから背景ピクセルを無視する方法

1)最初の手順で背景を削除します。私はhereというソリューションを使ってこれを行いました。それは完全に動作し、背景を黒くします。

2)最初のステップの結果で、私はhereというソリューションを使用して支配的な色を見つけようとしています。しかし、私は支配的な色の一つとしてblack(バックグラウンド)を取得しています。

手順2で背景ピ​​クセルを無視するにはどうすればよいですか?

+0

回答が良かったと思われる場合は、最善の回答を受け入れることを検討してください。 – m3h0w

答えて

0

背景を削除します。これにより、前景と背景の2値画像が得られます。フォアグラウンド画像に小さな穴を閉じ、輪郭を一般的にきれいにするために、形態学的に閉じます。最後に、ピクセルをもう一度置き換えて、カラーの前景イメージを取得します。

+0

これは質問に答えません - 彼らは前景イメージを持っています、彼らはクラスタリングするときに背景を無視する方法を知りたいです。 – ELRG

1

簡単な方法の1つは、黒を支配的な色として単に破棄することです。あなたが本当に望むよりも1つ多くのクラスターをつかむ、黒を無視する。黒色が本当に支配的な色になる場合は、別の背景色で操作を繰り返して破棄します。結果を比較する。これは遅くても簡単です。

また、フォアグラウンドのピクセルからのみサンプリングすることもできます。フォアグラウンド抽出法では、バイナリの白黒の前景/背景マスクが必要です。マスクの白い領域からのみサンプリングする場合は、これらの色のみを考慮する必要があります。

私はこれのC++実装を荒々しくしていますが、ほとんどの場合、可能な限り効率的ではありません。多分あなたが仕事を始めることができるでしょうか?

Mat src; //Your source image 
Mat mask; //Your black & white foreground/background image 
Mat samples(src.rows * src.cols, 3, CV_32F); 
//Set up samples with only foreground pixels 
for (int y = 0; y < src.rows; y++) { 
    for (int x = 0; x < src.cols; x++) { 
     if (mask.at<uchar>(y, x) == 255) { 
      for (int z = 0; z < 3; z++) { 
       samples.at<float>(y + x*src.rows, z) = src.at<Vec3b>(y, x)[z]; 
      } 
     } 
    } 
} 
int clusterNo = 3; 
int attempts = 5; 
Mat labels; 
Mat centers; 
kmeans(samples, clusterNo, labels, TermCriteria(), attempts, KMEANS_RANDOM_CENTERS, centers); 

ドミナントカラーはセンターの行に保存されます。そこでは、あなたが望むことができる色が保存されます。

2

場合によっては、関心のある領域の境界矩形を見つけることができます。カラーピクセルの数がその境界矩形内の黒ピクセルの数よりもはるかに多い場合、黒は支配的な色として検出される。

マスクのバイナリイメージでfindContours(binaryMask)を呼び出してください。あなたが探していた輪郭だけを見つけてください。そうでない場合は、フィルタリングしてアプリケーションに最適なフィルタを取得します。輪郭線にboundingRect(cnt)と呼んでください。次に、その長方形を使用して画像をトリミングし、関数を実行します。それが不十分な場合は、minAreaRect(cnt)を試してください。ただし、クロッピングは少しトリッキーです:see this answer

これがうまくいかない場合は、マスクの色をドレスに表示されない99%の色に変更してから、正確なRGBを知っている値 - 結果からフィルタリングします。

次回は、あなたのケースのイメージを提供することを忘れないでください。答えがより正確になる可能性があります。

関連する問題