0

私はコンピュータビジョンへの初心者だし、私はこのイメージ内のすべてのテストストリップを検出しようとしている:OpenCVでテストストリップを検出する方法は?

source

結果、私が取得しようとしている:

result

すべてのターゲットオブジェクトが長方形であり、固定されたアスペクト比を持つため、非常に簡単であると仮定します。しかし、どのアルゴリズムや関数を使うべきか分かりません。

OpenCVでエッジ検出と2D特徴検出の例を試しましたが、結果は理想的ではありません。これらの類似のオブジェクトをどのように検出すればよいでしょうか?

更新:

テストストリップは、色で、そしてもちろん、その結果線の陰影を変化させることができます。

variations of test strips

私はオンラインを見つけたほとんどの例は、複雑なオブジェクトのためのものであるとして、私は、オブジェクト検出のためにこれらの単純な機能を説明しなければならないのか分からない。しかし、彼らはすべての写真に示すように、同じ参照ラインを持っています建物や顔のように。

+1

ほんの少しのsugestions、1)背景(しきい値)を取り除こうとします。 2)行を見つけて、おそらく[hough line transform](http://docs.opencv.org/2。4/doc/tutorials/imgproc/imgtrans/hough_lines/hough_lines.html)は、3)そのような線の交差点を見つけることができます4)この交差点と長方形を作成します。ボーナス)あなたは残りの部分からオブジェクト(輪郭)を分離し(残り=黒)、結果を混乱させる可能性のある他のデータなしで1対1で分析しようとするかもしれません – api55

+0

それらのバリエーションを見るためのイメージはありますか? –

+0

@ MarkSetchell更新情報を参照してください – zhengyue

答えて

2

解決策は正確ではありませんが、それは良い出発点です。あなたはしかし、パラメーターを再生する必要があります。ある閾値方法を使用してストリップを分割し、次に@ api55として個別にハフラインを適用すると、大きな助けになります。

ここに私が得た結果があります。

after laplacianafter thresholding and median filteringfinal image

コード。

import cv2 
import numpy as np 

# read image 
img = cv2.imread('KbxN6.jpg') 
# filter it 
img = cv2.GaussianBlur(img, (11, 11), 0) 
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 

# get edges using laplacian 
laplacian_val = cv2.Laplacian(gray_img, cv2.CV_32F) 

# lap_img = np.zeros_like(laplacian_val, dtype=np.float32) 
# cv2.normalize(laplacian_val, lap_img, 1, 255, cv2.NORM_MINMAX) 
# cv2.imwrite('laplacian_val.jpg', lap_img) 

# apply threshold to edges 
ret, laplacian_th = cv2.threshold(laplacian_val, thresh=2, maxval=255, type=cv2.THRESH_BINARY) 
# filter out salt and pepper noise 
laplacian_med = cv2.medianBlur(laplacian_th, 5) 
# cv2.imwrite('laplacian_blur.jpg', laplacian_med) 
laplacian_fin = np.array(laplacian_med, dtype=np.uint8) 

# get lines in the filtered laplacian using Hough lines 
lines = cv2.HoughLines(laplacian_fin,1,np.pi/180,480) 
for rho,theta in lines[0]: 
    a = np.cos(theta) 
    b = np.sin(theta) 
    x0 = a*rho 
    y0 = b*rho 
    x1 = int(x0 + 1000*(-b)) 
    y1 = int(y0 + 1000*(a)) 
    x2 = int(x0 - 1000*(-b)) 
    y2 = int(y0 - 1000*(a)) 
    # overlay line on original image 
    cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2) 

# cv2.imwrite('processed.jpg', img) 
# cv2.imshow('Window', img) 
# cv2.waitKey(0) 
+0

ありがとう!私は試して結果を更新します。 – zhengyue

0

これは、cannyエッジ検出と組み合わせてfindCountours関数を使用することによる代替ソリューションです。コードはこのtutorial

import cv2 
import numpy as np 
import imutils 

image = cv2.imread('test.jpg') 
resized = imutils.resize(image, width=300) 
ratio = image.shape[0]/float(resized.shape[0]) 

# convert the resized image to grayscale, blur it slightly, 
# and threshold it 
gray = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY) 
edges = cv2.Canny(resized,100,200) 
cv2.imshow('dsd2', edges) 
cv2.waitKey(0) 
cnts = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, 
    cv2.CHAIN_APPROX_NONE) 
cnts = cnts[0] if imutils.is_cv2() else cnts[1] 
sd = ShapeDetector() 

# loop over the contours 
for c in cnts: 
    # compute the center of the contour, then detect the name of the 
    # shape using only the contour 
    M = cv2.moments(c) 
    cX = int((M["m10"]/M["m00"]) * ratio) 
    cY = int((M["m01"]/M["m00"]) * ratio) 


    # multiply the contour (x, y)-coordinates by the resize ratio, 
    # then draw the contours and the name of the shape on the image 
    c = c.astype("float") 
    c *= ratio 
    c = c.astype("int") 
    cv2.drawContours(image, [c], -1, (0, 255, 0), 2) 
    #show the output image 
    #cv2.imshow("Image", image) 
    #cv2.waitKey(0) 
cv2.imwrite("erg.jpg",image) 

結果に非常にわずかに基づいています。

  • 画像: enter image description here


    私はそれは、以下のパラメータチューニングすることによって改善することができると思いますサイズ変更幅

  • CHAIN_APPROX_NONE(findContour Docs

多分も小さな輪郭をフィルタリングまたは近接している輪郭をマージする便利です。

関連する問題