Je dois détecter la voie de circulation d'une vidéo. Voici ma façon de le faire.Python et OpenCV - Amélioration de mon algorithme de détection de voie
- Déterminer en découpant l'image (focus la partie centrale)
- Niveaux de gris le retour sur investissement
- Equalized le retour sur investissement en niveaux de gris avec
cv2.equalizeHist
- Appliquer le flou gaussien (3) la région d'intérêt (ROI)
- seuil (4) à l'aide
cv2.adaptiveThreshold
- squelettisent (5) à l'aide de
skimage.morphology.skeletonize
- Appliquer le
cv2.HoughLines
sur (6)
Pour le cv2.HoughLines
, je mis en place afin que:
- Si
rho
est positif (ce qui signifie que la ligne droite est en pente vers la droite (bottom-up), il ne tracez la ligne que si elle est à certains angles (j'établis la plage de l'angle)) - Si
rho
est négatif (la ligne droite est inclinée vers la gauche (bottom-up), elle ne tracera la ligne que si elle est est à certains angles)
Ceci est mon code pour dessiner les lignes:
lines = cv2.HoughLines(image_bin, 1, np.pi/180, 50)
try:
range = lines.shape[0]
except AttributeError:
range = 0
for i in xrange(range):
for rho, theta in lines[i]:
if rho > 0 and (np.pi*1/10 < theta < np.pi*4/10):
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))
cv2.line(roi, (x1, y1), (x2, y2), (0, 255, 0))
if rho < 0 and (np.pi*7/10 < theta < np.pi*9/10):
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))
cv2.line(roi, (x1, y1), (x2, y2), (0, 255, 0))
Si je ne fais pas ce que je viens de faire ci-dessus pour la fonction cv2.HoughLines
, je crois qu'il y aura beaucoup de lignes inutiles tirées. Après avoir réglé les paramètres et autres, j'ai obtenu un très bon résultat, mais pour une seule image. Je ne pense pas que ce soit aussi bon pour une vidéo qui continuera à changer. Ce qui me dérange le plus, c'est mon algorithme pour dessiner les lignes nécessaires (c'est la voie de la route). Y a-t-il une meilleure façon? Au moins mieux que le mien.
Ceci est mon résultat:
histogramme égalisées, seuillée, et l'image squeletté du ROI:
Comment puis-je 'broder' les lignes? Désolé, toujours un débutant dans la programmation et le traitement d'image. – Hilman
J'ai ajouté quelques notes. Désolé de ne pas fournir de code. C'est en C++, et l'implémentation particulière est très différente de la vôtre - en fait, je n'ai tout simplement pas assez de temps pour l'adapter à votre application. – Aenimated1