2014-04-20 43 views
5

我是OpenCV的新手,有幾個問題。我需要根據它們的形狀來檢測瓶子或罐子。爲此我使用覆盆子pi板和pi相機。背景總是黑色,不會改變。我已經嘗試了很多可能的解決方案來解決這個問題,但是得不到滿意的結果我嘗試過的東西包括邊緣檢測,形態轉換,matchShapes(),matchTemplate()。請讓我知道我是否能夠以最高的準確性有效地完成這項任務。在opencv中檢測罐頭或瓶子

樣本圖像:

enter image description here

+0

因此,除了瓶子以外,現場不會有任何物體? – Haris

+0

在給定的時間內,除了瓶子或罐子之外,不會有任何物品。 – user3553000

+1

然後應用[二進制翻轉閾值](http://docs.opencv.org/doc/tutorials/imgproc/threshold/threshold.html#threshold-binary-inverted)以較低值獲取前景。 – Haris

回答

3

我想出了一個方法,可以幫助!如果您對罐頭有更多的瞭解,即寬度與高度的比例,則可以通過調整矩形尺寸來增強其穩健性!

方法

  • 轉換圖像HSV色彩空間。將V增加2倍,以獲得更多可見的東西。
  • 查找Sobel衍生品xy方向。計算兩個方向的權重相等。
  • 使用Otsu方法閾值您的圖像。
  • Closing應用於您的圖像。
  • 應用Canny邊緣檢測器。
  • 查找Hough Line Transform
  • 查找行距圖像的邊界矩形。
  • 疊加到你的圖像(最後完成的:P)。

代碼

image = cv2.imread('image3.jpg', cv2.IMREAD_COLOR) 
original = np.copy(image) 
if image is None: 
    print 'Can not read/find the image.' 
    exit(-1) 

hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) 
H,S,V = hsv_image[:,:,0], hsv_image[:,:,1], hsv_image[:,:,2] 
V = V * 2 

hsv_image = cv2.merge([H,S,V]) 
image = cv2.cvtColor(hsv_image, cv2.COLOR_HSV2RGB) 
image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) 
# plt.figure(), plt.imshow(image) 

Dx = cv2.Sobel(image,cv2.CV_8UC1,1,0) 
Dy = cv2.Sobel(image,cv2.CV_8UC1,0,1) 
M = cv2.addWeighted(Dx, 1, Dy,1,0) 

# plt.subplot(1,3,1), plt.imshow(Dx, 'gray'), plt.title('Dx') 
# plt.subplot(1,3,2), plt.imshow(Dy, 'gray'), plt.title('Dy') 
# plt.subplot(1,3,3), plt.imshow(M, 'gray'), plt.title('Magnitude') 

ret, binary = cv2.threshold(M,10,255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) 
# plt.figure(), plt.imshow(binary, 'gray') 

binary = binary.astype(np.uint8) 
binary = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (20, 20))) 
edges = cv2.Canny(binary, 50, 100) 
# plt.figure(), plt.imshow(edges, 'gray') 

lines = cv2.HoughLinesP(edges,1,3.14/180,50,20,10)[0] 
output = np.zeros_like(M, dtype=np.uint8) 
for line in lines: 
    cv2.line(output,(line[0],line[1]), (line[2], line[3]), (100,200,50), thickness=2) 
# plt.figure(), plt.imshow(output, 'gray') 

points = np.array([np.transpose(np.where(output != 0))], dtype=np.float32) 
rect = cv2.boundingRect(points) 
cv2.rectangle(original,(rect[1],rect[0]), (rect[1]+rect[3], rect[0]+rect[2]),(255,255,255),thickness=2) 
original = cv2.cvtColor(original,cv2.COLOR_BGR2RGB) 
plt.figure(), plt.imshow(original,'gray') 


plt.show() 

注:您可以取消該行用於顯示每個步驟的結果!爲了可讀性,我只是對它們發表評論。

結果

Result Image

注:如果你知道你的長寬比可以您可以修復它更好!

我希望這會有所幫助。祝你好運:)

+1

非常感謝您的評論。我想我可以計算罐子或瓶子的長寬比。我應該比較矩形的高度和寬度與標準罐尺寸。 – user3553000