0

私はopenCVが初めてで、Android用に提供されているサンプルに取り組んでいます。

私の目標は色の塊を検出することなので、色の塊の検出サンプルから始めました。

カラー画像をグレースケールに変換してから、バイナリしきい値を使用してしきい値処理しています。

背景は白、ブロブは黒です。それらの黒い塊を検出したい。また、輪郭をカラーで描きたいのですが、画像が白黒なのでできません。

グレースケールでこれを達成することができましたが、輪郭の描画方法は好みません。色の許容範囲が高すぎて、輪郭が実際のブロブよりも大きいようです (ブロブが小さすぎる可能性がありますか?)。私が話しているこの「許容範囲」は setHsvColor と関係があると思いますが、その方法はよくわかりません。

前もって感謝します!よろしくお願いします

より多くの情報を更新

追跡したい画像は、インクスプリットです。黒いインクの裂け目がある白い紙を想像してみてください。今はリアルタイム(カメラビュー)でやっています。実際のアプリは写真を撮り、その写真を分析します。

上で述べたように、openCV GitHub リポジトリから color-blob-detection サンプル (android) を取得しました。そして、このコードをonCameraFrameメソッドに追加します (リアルタイムで白黒に変換するため) 変換が行われるため、インクが黒、青、赤のいずれであってもかまいません。

mRgba = inputFrame.rgba();
/**************************************************************************/
/** BLACK AND WHITE **/
// Convert to Grey
Imgproc.cvtColor(inputFrame.gray(), mRgba, Imgproc.COLOR_GRAY2RGBA, 4);

Mat blackAndWhiteMat = new Mat ( H, W, CvType.CV_8U, new Scalar(1));
double umbral = 100.0;
Imgproc.threshold(mRgba, blackAndWhiteMat , umbral, 255, Imgproc.THRESH_BINARY);

// convert back to bitmap for displaying
Bitmap resultBitmap = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);
blackAndWhiteMat.convertTo(blackAndWhiteMat, CvType.CV_8UC1);
Utils.matToBitmap(blackAndWhiteMat, resultBitmap);
/**************************************************************************/

これは最善の方法ではないかもしれませんが、うまくいきます。

ここで、黒いブロブ (インクの分裂) を検出したいと考えています。Logcat(サンプルアプリのログエントリ)が検出された輪郭の数をスローするため、それらが検出されたと思いますが、画像が白黒で、輪郭を赤くしたいなどの理由でそれらを見ることができません。

画像の例を次に示します。 ここに画像の説明を入力

そして、これがRGBを使用して取得したものです(白黒画像ではなく、そのままの色のブロブ検出)。小さなブロブが検出されないことに注意してください。(検出できるか、小さすぎるか) ここに画像の説明を入力

ご協力いただきありがとうございます!さらに情報が必要な場合は、この質問を喜んで更新します

更新: color-blob-detection サンプルの GitHub リポジトリ (2 番目の画像)

Android用openCVサンプルのGitHubリポジトリ

4

1 に答える 1

0

このソリューションは、適応型画像しきい値処理と連結成分アルゴリズムの使用の組み合わせに基づいています。

仮定- 用紙はイメージの最も明るい領域であり、用紙上のインク スポットは最も暗い領域です。

from random import Random
import numpy as np
import cv2

def random_color(random):
    """
    Return a random color
    """
    icolor = random.randint(0, 0xFFFFFF)
    return [icolor & 0xff, (icolor >> 8) & 0xff, (icolor >> 16) & 0xff]

#Read as Grayscale
img = cv2.imread('1-input.jpg', 0)
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)

# Gaussian to remove noisy region, comment to see its affect.
img = cv2.medianBlur(img,5)

#Find average intensity to distinguish paper region
avgPixelIntensity = cv2.mean( img )
print "Average intensity of image: ", avgPixelIntensity[0]

# Generate mask to distinguish paper region
#0.8 - used to ignore ill-illuminated region of paper
mask = cv2.inRange(img, avgPixelIntensity[0]*0.8, 255) 
mask = 255 - mask
cv2.imwrite('2-maskedImg.jpg', mask)

#Approach 1
# You need to choose 4 or 8 for connectivity type(border pixels)
connectivity = 8
# Perform the operation
output = cv2.connectedComponentsWithStats(mask, connectivity, cv2.CV_8U)
# The first cell is the number of labels
num_labels = output[0]
# The second cell is the label matrix
labels = output[1]
# The third cell is the stat matrix
stats = output[2]
# The fourth cell is the centroid matrix
centroids = output[3]

cv2.imwrite("3-connectedcomponent.jpg", labels)
print "Number of labels", num_labels, labels

# create the random number
random = Random()

for i in range(1, num_labels):
    print stats[i, cv2.CC_STAT_LEFT], stats[i, cv2.CC_STAT_TOP], stats[i, cv2.CC_STAT_WIDTH], stats[i, cv2.CC_STAT_HEIGHT]
    cv2.rectangle(cimg, (stats[i, cv2.CC_STAT_LEFT], stats[i, cv2.CC_STAT_TOP]), 
        (stats[i, cv2.CC_STAT_LEFT] + stats[i, cv2.CC_STAT_WIDTH], stats[i, cv2.CC_STAT_TOP] + stats[i, cv2.CC_STAT_HEIGHT]), random_color(random), 2)

cv2.imwrite("4-OutputImage.jpg", cimg)

入力画像

入力画像

しきい値処理および反転操作からのマスクされたイメージ。

マスクされた画像

接続されたコンポーネントの使用。

CC画像

入力画像に連結成分の出力を重ねる。

出力画像

于 2016-11-26T17:41:53.883 に答える