Prima di tutto, questo esempio mostra solo come disegnare contorni con la semplice approssimazione. Se dovessi mostrare quell'immagine ora, otterrai solo ciò che vedi sul lato destro di quella figura. Se si desidera ottenere l'immagine sul lato sinistro, è necessario rilevare il contorno completo. Nello specifico, è necessario sostituire il flag cv2.CHAIN_APPROX_SIMPLE
con cv2.CHAIN_APPROX_NONE
. Date un'occhiata al documento OpenCV su findContours
per ulteriori dettagli: http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#findcontours
Inoltre, il vostro codice disegna i contorni sull'immagine, ma non visualizza i risultati. Avrai bisogno di chiamare cv2.imshow
per quello.
Come tale, creare due immagini in questo modo:
# Your code
import numpy as np
import cv2
im = cv2.imread('test.jpg')
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,0)
# Detect contours using both methods on the same image
contours1, _ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
contours2, _ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# Copy over the original image to separate variables
img1 = im.copy()
img2 = im.copy()
# Draw both contours onto the separate images
cv2.drawContours(img1, contours1, -1, (255,0,0), 3)
cv2.drawContours(img2, contours2, -1, (255,0,0), 3)
Ora, per ottenere la cifra che vedete qui sopra, ci sono due modi per farlo:
- Crea un immagine che memorizza entrambi questi risultati insieme, quindi mostra questa immagine combinata.
- Utilizzare
matplotlib
, combinato con subplot
e imshow
in modo da poter visualizzare due immagini in una finestra.
ti faccio vedere come si fa utilizzando entrambi i metodi:
Metodo # 1
Semplicemente pila lato due immagini affiancate, quindi mostrare l'immagine dopo:
out = np.hstack([img1, img2])
# Now show the image
cv2.imshow('Output', out)
cv2.waitKey(0)
cv2.destroyAllWindows()
I li impila orizzontalmente in modo che siano un'immagine combinata, quindi mostrarli con cv2.imshow
.
Metodo # 2
È possibile utilizzare matplotlib
:
import matplotlib.pyplot as plt
# Spawn a new figure
plt.figure()
# Show the first image on the left column
plt.subplot(1,2,1)
plt.imshow(img1[:,:,::-1])
# Turn off axis numbering
plt.axis('off')
# Show the second image on the right column
plt.subplot(1,2,2)
plt.imshow(img2[:,:,::-1])
# Turn off the axis numbering
plt.axis('off')
# Show the figure
plt.show()
Questo dovrebbe visualizzare sia immagini in sottofigure separati all'interno di una finestra globale figura. Se date un'occhiata a come sto chiamando imshow
qui, vedrete che sto scambiando i canali RGB perché OpenCV legge in immagini in formato BGR. Se si desidera visualizzare le immagini con matplotlib
, è necessario invertire i canali poiché le immagini sono in formato RGB (come dovrebbero essere).
Per rispondere alla sua domanda nei commenti, si prenderebbe quale struttura di contorno che si desidera (o contours1
contours2
) e cercare i punti di contorno. contours
è un elenco di tutti i contorni possibili e all'interno di ciascun contorno c'è una matrice 3D che è modellata in un formato N x 1 x 2
. N
sarebbe il numero totale di punti che rappresentano il contorno. Rimuoverò la seconda dimensione di singleton in modo che possiamo ottenere che questa sia una matrice N x 2
. Inoltre, usiamo la rappresentazione completa dei contorni per ora:
points = contours1[0].ravel().reshape((len(contours1[0]),2))
sto per scontato che l'immagine ha solo un oggetto, da qui la mia indicizzazione in contours1
con indice 0. I dipanare la matrice in modo che diventa un vettore a riga singola, quindi rimodella la matrice in modo che diventi N x 2
. Quindi, siamo in grado di trovare il punto di minimo da:
min_x = np.argmin(points[:,0])
min_point = points[min_x,:]
np.argmin
trova la posizione del valore più piccolo in una matrice che si fornisce. In questo caso, vogliamo operare lungo la coordinata x
o le colonne. Una volta trovata questa posizione, semplicemente indicizziamo il nostro array di punti di contorno 2D ed estraiamo il punto del contorno.
questa è una risposta più dettagliata e completa. Grazie mille –
Oh mio piacere :) Non intendevo rubarlo da runDOSrun, ma in mia difesa, stavo lavorando a questa risposta mentre lui postava. Buona fortuna! – rayryeng
Posso sembrare scortese se ti faccio una domanda finale perché questo sito dice che devo aspettare 90 minuti prima di chiedere nuovamente. Voglio stampare le coordinate del pixel che è l'armadio dell'asse Y (significa che la sua coordinata x è la più piccola) e che appartiene ai contorni. Potrebbe essere troppo semplice per te? Sono solo al livello principiante –