2017-03-05 12 views
0

私は、私が作る部品にこだわった破片を見つけるためのプログラムに取り組んでいます。これまで私は、クリーンな部品とその中にチップを含む部品を取り出し、2つの画像を減算して、2つの画像の間に差異を残すことができました。私が理解していないのは、バイナリイメージでこのアイテムを検出する方法です。これまではSimpleBlobDetector関数を使用していましたが、イメージをあまりにもぼかすだけで機能するようになりましたので、小さな破片では機能しないと懸念していました。私は広範囲のぼかしをすることなくオリジナルを検出できるようにしたい。どんな助けもありがとう。コードと画像は以下の通りです。Opencvバイナリアイテムの検出

import cv2 
import numpy as np 

#Load Images 
tempImg = cv2.imread('images/partchip.jpg') 
lineImg = cv2.imread('images/partnochip.jpg') 

#Crop Images 
cropTemp = tempImg[460:589, 647:875] 
cropLine = lineImg[460:589, 647:875] 

#Gray Scale 
grayTemp = cv2.cvtColor(cropTemp,cv2.COLOR_BGR2GRAY) 
grayLine = cv2.cvtColor(cropLine,cv2.COLOR_BGR2GRAY) 

#Subtract Images 
holder = cv2.absdiff(grayTemp,grayLine) 

#THreshold Subtracted Image 
th, imgDiff = cv2.threshold(holder, 160, 255, cv2.THRESH_BINARY_INV) 

#Blur Image 
#blur = imgDiff 
blur = cv2.blur(imgDiff,(20,20)) 

#Detect Blobs 
detector = cv2.SimpleBlobDetector_create() 
blob = detector.detect(blur) 


imgkeypoints = cv2.drawKeypoints(blur, blob, np.array([]), (0,255,0), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) 
originalWithPoints=cv2.drawKeypoints(cropTemp, blob, np.array([]), (0,255,0), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) 

cv2.namedWindow("Template", cv2.WINDOW_NORMAL) 
cv2.namedWindow("Line", cv2.WINDOW_NORMAL) 
cv2.namedWindow("Difference", cv2.WINDOW_NORMAL) 

cv2.resizeWindow("Template", 500, 300) 
cv2.resizeWindow("Line", 500, 300) 
cv2.resizeWindow("Difference", 500, 300) 


cv2.imshow('Template',originalWithPoints) 
cv2.imshow('Line',cropLine) 
cv2.imshow('Difference',imgkeypoints) 


cv2.waitKey(0) 
cv2.destroyAllWindows() 

Part with chip Part with No Chip

+0

作業中の画像をアップロードできますか? –

+0

ちょうど、彼らはコードの下にリンクされています – shark38j

+0

しかし、あなたがアップロードした2つの画像の間に(視覚的な)違いがないようです – ZdaR

答えて

1

私は異常を見つけるためにあなたのコードを使用していました。私はimgDiffバイナリイメージ上で最大の面積を持つ輪郭を得ました。それを使って、私は長方形でそれを束縛することができました。

enter image description here

私は、これはあなたが探しているものであると思います....

EDIT:

注:

私は以下のコードと一緒に手順を説明しました:オブジェクトが白い場合は等高線が見つかるため、imgDiffcv2.bitwise_not(imgDiff)で反転してください。

#---Finding the contours present in 'imgDiff'--- 
_, contours,hierarchy = cv2.findContours(imgDiff,2,1) 

ff = 0 #----to determine which contour to select--- 
area = 0 #----to determine the maximum area--- 
for i in range(len(contours)): 
    if(cv2.contourArea(contours[i]) > area): 
     area = cv2.contourArea(contours[i]) 
     ff = i 

#---Bounding the contour having largest area--- 
x,y,w,h = cv2.boundingRect(contours[ff]) 
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2) 
cv2.imshow('fin.jpg',img) 
+0

Jeru、そのコードを投稿できますか?それはまさに私が探していたものですが、私は最大のエリアを見つける方法がわかりませんでした。再度、感謝します!!! – shark38j