2014-04-20 12 views
5

Sono nuovo di OpenCV e ho alcune domande. Devo rilevare una bottiglia o una lattina in base alla loro forma. Per questo sto usando una tavola pi lampone pi fotocamera. Lo sfondo è sempre nero e non cambia. Ho provato molte possibili soluzioni a questo problema ma non ho potuto ottenere risultati soddisfacenti. Le cose che ho provato includono il rilevamento dei bordi, le trasformazioni morfologiche, matchShapes(), matchTemplate(). Per favore fatemi sapere se posso fare questo compito in modo efficiente e con la massima precisione.Rilevazione di una lattina o bottiglia in opencv

Un esempio di immagine:

enter image description here

+0

Quindi non ci sarà alcun oggetto nella scena, oltre alla bottiglia ?. – Haris

+0

Non ci saranno oggetti diversi da una bottiglia o da una lattina in un dato momento. – user3553000

+1

Quindi applicare [soglia invertita binaria] (http://docs.opencv.org/doc/tutorials/imgproc/threshold/threshold.html#threshold-binary-inverted) con valore basso, per ottenere il primo piano. – Haris

risposta

3

mi si avvicinò con un approccio che può aiutare! Se sai più cose sulla lattina, cioè il rapporto larghezza-altezza, può essere più robusto regolando la dimensione del rettangolo!

approccio

  • immagine Converti in HSV spazio colore. Aumentare di V di un fattore 2 per avere più cose visibili.
  • Trova Sobel derivati ​​in x e direzione. Grandezza di calcolo con peso uguale per entrambe le direzioni.
  • Soglia l'immagine utilizzando il metodo Otsu.
  • Applicare Closing all'immagine.
  • Applicare il rivelatore del bordo Canny.
  • Trova Hough Line Transform.
  • Trova rettangolo limite dell'immagine della tua linea.
  • sovrapporlo sulla vostra immagine (finalmente fatto: P).

Codice

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() 

Nota: è possibile rimuovere il commento le linee per mostrare il risultato di ogni passo! Li ho solo commentati per motivi di leggibilità.

Risultato

Result Image

NOTA: Se si conosce il rapporto di aspetto del vostro può si può risolvere il problema meglio!

Spero che possa essere d'aiuto. Buona fortuna :)

+1

Grazie mille per il tuo commento. Penso di poter calcolare le proporzioni di una lattina o di una bottiglia. Dovrei confrontare l'altezza e la larghezza del rettangolo con le dimensioni standard delle lattine. – user3553000