2012-06-29 15 views
11

私はOpenCVでブロブを検出するAndroidアプリを書いています。 1つのタスクは、前景オブジェクトを背景と区別するために画像を閾値処理することである(画像参照)。ヒストグラムからしきい値を取得する方法は?

イメージがわかっていて、しきい値()に手動でしきい値を渡すことができれば問題ありません。この特定のイメージでは、イメージは200です。しかし、そこにある唯一の知識どのように私は動的にしきい値を把握することができます暗い固体の背景と軽い前景オブジェクトでしょうか?

私はグレースケール画像の輝度分布を計算できるヒストグラムを見つけました。しかし、私はヒストグラムを分析し、関心のあるオブジェクト(より軽い)が存在する値を選択する方法を見つけることができませんでした。あれは;私は明白な暗いバックグラウンドのスパイクとより明るい前景のスパイクを区別したい - この場合は200以上ですが、別のケースではオブジェクトが灰色がかった場合は100と言うことができます。あなたは背景が暗い(黒)であると前景が軽いと言うなら

enter image description here

+4

There'saそのための方法の束。多分大津の方法があなたのために働くかもしれません。そうでなければ、まだ良い出発点IMHOです。 http://en.wikipedia.org/wiki/Otsu%27s_Method – Florian

+0

100個のしきい値が良い画像をアップロードできますか? 50以上のスレッショルドの画像でも許容できるので... – ArtemStorozhuk

答えて

9

すべての画像がこのようなものである場合、またはこのスタイルにすることができる場合、私はcv2.THRESHOLD_OTSUと考えます。つまり、otsuのしきい値アルゴリズムは良いショットです。

>>> import cv2 
>>> import numpy as np 
>>> img2 = cv2.imread('D:\Abid_Rahman_K\work_space\sofeggs.jpg',0) 

>>> ret,thresh = cv2.threshold(img2,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) 

>>> ret 
122.0 

retが自動的に計算された閾値である:

は、以下のコマンド端子にはPythonを使用したサンプルです。このためにしきい値として「0」を渡します。

私はGIMPで124を得ました(私たちが得た結果に匹敵します)。また、ノイズを除去します。下の結果を参照してください:

enter image description here

6

は、その後、私はので、(のYCrCb、などのようにYXXまたはその他のYUV color spaceを使用することをお勧めしますそのような色空間の第1の成分は、輝度(または稲妻)である。

light channel

のでYチャンネルは(extractChennel機能を経由して)抽出された後、私たちは、このチャネル(画像)のヒストグラムを分析する必要があります。

histogram

は、(最初​​のを参照してください。左)こんにちは?これは、画像上の暗い領域(状況の背景)を表します。ですから、私たちの目標は、このこぶを含むセグメント(横座標に、画像の赤い部分です)を見つけることです。明らかに、このセグメントの左の点はゼロです。

は、ヒストグラムの(ローカル)最大ポイント
  • ヒストグラムの値がいくつかの小さなイプシロン未満であるの左からである
    • (あなたがそれを設定することができます右のポイントは最初のポイントです10)

    このヒストグラムのセグメントの右端の位置を示す緑の垂直線が描かれています。

    それだけです!セグメントのこの右の点が必要なしきい値です。ここでの結果です(イプシロンは10で、計算しきい値は50です):

    result

    私はあなたが上の画像のノイズを削除することは問題ではないということだと思います。

  • 0

    以下は、OpenCVの3.xのと連携ABIDの回答のC++実装です:元画像に対して、これを実行する

    // Convert the source image to a 1 channel grayscale: 
    Mat gray; 
    cvtColor(src, gray, CV_BGR2GRAY); 
    // Apply the threshold function with the CV_THRESH_OTSU setting as well 
    // You can skip having it return the value, but I include it for showing the 
    // results from OTSU 
    double thresholdValue = threshold(gray, gray, 0, 255, CV_THRESH_BINARY+CV_THRESH_OTSU); 
    // Present the threshold value 
    printf("Threshold value: %f\n", thresholdValue); 
    

    、私は次のGET: enter image description here

    OpenCVは、答えにAbidの値に近い値122を計算しました。

    enter image description here

    をして、次のように生産、178の新しい閾値と::ちょうど検証する

    、私はここに見られるように、元の画像を変更

    enter image description here

    関連する問題