diff --git a/labyrinthe/6-jumeaux/test/#cam_bille-test.py# b/labyrinthe/6-jumeaux/test/#cam_bille-test.py# new file mode 100644 index 0000000..b1897b7 --- /dev/null +++ b/labyrinthe/6-jumeaux/test/#cam_bille-test.py# @@ -0,0 +1,105 @@ +import os, time +import numpy as np +import cv2 as cv + +############################################################################### +# cam_bille-test.py : +# @title: Détection de la bille par vision (caméra + OpenCV) +# @project: Blender-EduTech - Tutoriel : Tutoriel 6 : Labyrinthe à bille - Développement de jumeau numérique +# @lang: fr +# @authors: Philippe Roy +# @copyright: Copyright (C) 2023 Philippe Roy +# @license: GNU GPL +############################################################################### + +### +# Installation : +# - pip3 install opencv-python +### + +############################################################################### +# Paramètres de reconnaissance de la bille +############################################################################### + +# Rayon pour une bille de 9 mm +rayon_min, rayon_max = 8, 10 + +# Cadre carré du labyrinthe avec une bordure de 10 px et un image de 640x480 px +cadre_cote = 460 +cadre_x0= round((480/2)-(cadre_cote/2)) +cadre_x1= round((480/2)+(cadre_cote/2)) +cadre_y0 = round((640/2)-(cadre_cote/2)) +cadre_y1 = round((640/2)+(cadre_cote/2)) + +############################################################################### +# Initialisation +############################################################################### + +# Init de la caméra +cam_id = 0 # 0 pour la 1ere camera, 1 pour la seconde ... +cam = cv.VideoCapture(cam_id) # 0 pour la 1ere camera, 1 pour la +assert cam.isOpened(), "Erreur lors de l'ouverture de la camera !" + +# Création de la fenêtre d'affichage +# cv.namedWindow("Caméra") + +############################################################################### +# Affichage +############################################################################### + +# Capture vidéo +echap='' +while cam.isOpened(): + cam_actif, cam_img_orig = cam.read() + cam_img = cv.rotate(cam_img_orig, cv.ROTATE_90_CLOCKWISE) + cam_gray = cv.cvtColor(cam_img, cv.COLOR_BGR2GRAY) + # cam_gray = cv.medianBlur(cam_gray, 5) # Réduction de la netteté + # (thresh, cam_bw) = cv.threshold(gray, 127, 255, cv.THRESH_BINARY) # Noir et blanc + rows = cam_gray.shape[0] + + # Version initiale + # cercles = cv.HoughCircles(cam_gray, cv.HOUGH_GRADIENT, 1, rows / 8, param1=100, param2=30, minRadius=rayon_min, maxRadius=rayon_max) + + # Un lent mais fiable + # cercles = cv.HoughCircles(cam_gray, cv.HOUGH_GRADIENT, 1, rows/10, param1=100, param2=15, minRadius=rayon_min, maxRadius=rayon_max) # un peu lent + + # Rapide mais avec beaucoup de faux positif -> contrôle cinématique + cercles = cv.HoughCircles(cam_gray, cv.HOUGH_GRADIENT, 1.5, rows/10, param1=100, param2=15, minRadius=rayon_min, maxRadius=rayon_max) + + # Archives ... + # cercles = cv.HoughCircles(cam_gray, cv.HOUGH_GRADIENT, 1, rows / 8, param1=30, param2=15, minRadius=rayon_min, maxRadius=rayon_max) + # cercles = cv.HoughCircles(cam_gray, cv.HOUGH_GRADIENT, 1.5, rows / 8, param1=100, param2=30, minRadius=rayon_min, maxRadius=rayon_max) + # cercles = cv.HoughCircles(cam_gray, cv.HOUGH_GRADIENT, 1, rows / 8, param1=100, param2=30, minRadius=5, maxRadius=10) + + # Dessin de la zone de détection + cv.rectangle(cam_img, (cadre_x0, cadre_y0), (cadre_x1, cadre_y1), (0, 0, 255), 2) # Contour du cadre de détection + cv.rectangle(cam_gray, (cadre_x0, cadre_y0), (cadre_x1, cadre_y1), (0, 0, 255), 2) # Contour du cadre de détection + + # Détection de la bille + if cercles is not None: + cercles = np.uint16(np.around(cercles)) + for i in cercles[0, :]: + cx, cy, r = i[0], i[1], i[2] + if cx > cadre_x0 and cx< cadre_x1 and cy > cadre_y0 and cy< cadre_y1: # Supression en dehors de la zone de détection + cv.circle(cam_img, (cx, cy), 1, (255, 0, 255), 2) # Point des centres + cv.circle(cam_gray, (cx, cy), 1, (255, 0, 255), 2) # Point des centres + r = i[2] + print ("Rayon :", r, "- Centre :", cx, cy) + cv.circle(cam_img, (cx, cy), r, (255, 0, 255), 2) # Contour des cercles + cv.circle(cam_gray, (cx, cy), r, (255, 0, 255), 2) # Contour des cercles + + cv.imshow("Detection de cercles", cam_img) # "Détection" -> bug ! + # cv.imshow("Detection de cercles", cam_gray) # "Détection" -> bug ! + # cv.imwrite("camera.png", cam_img) # Enregister l'image + + # Sortir + echap = cv.waitKey(1) # Saisie clavier avec un timeout de 1 ms + if echap & 0xFF == ord('q') or echap == 27 : + break + +############################################################################### +# Quitter +############################################################################### + +cam.release() +cv.destroyAllWindows() diff --git a/labyrinthe/6-jumeaux/test/.#cam_bille-test.py b/labyrinthe/6-jumeaux/test/.#cam_bille-test.py new file mode 120000 index 0000000..1028f52 --- /dev/null +++ b/labyrinthe/6-jumeaux/test/.#cam_bille-test.py @@ -0,0 +1 @@ +phroy@debian.94838:1699716570 \ No newline at end of file diff --git a/labyrinthe/6-jumeaux/test/cam_bille-test.py b/labyrinthe/6-jumeaux/test/cam_bille-test.py index 62c862c..21f9e3f 100644 --- a/labyrinthe/6-jumeaux/test/cam_bille-test.py +++ b/labyrinthe/6-jumeaux/test/cam_bille-test.py @@ -51,25 +51,26 @@ assert cam.isOpened(), "Erreur lors de l'ouverture de la camera !" echap='' while cam.isOpened(): cam_actif, cam_img_orig = cam.read() - cam_img = cv.rotate(cam_img_orig, cv.ROTATE_90_COUNTERCLOCKWISE) + cam_img = cv.rotate(cam_img_orig, cv.ROTATE_90_CLOCKWISE) cam_gray = cv.cvtColor(cam_img, cv.COLOR_BGR2GRAY) - # cam_gray = cv.medianBlur(cam_gray, 5) # Réductoin de la netteté + # cam_gray = cv.medianBlur(cam_gray, 5) # Réduction de la netteté # (thresh, cam_bw) = cv.threshold(gray, 127, 255, cv.THRESH_BINARY) # Noir et blanc rows = cam_gray.shape[0] # Version initiale # cercles = cv.HoughCircles(cam_gray, cv.HOUGH_GRADIENT, 1, rows / 8, param1=100, param2=30, minRadius=rayon_min, maxRadius=rayon_max) + # Un lent mais fiable + # cercles = cv.HoughCircles(cam_gray, cv.HOUGH_GRADIENT, 1, rows/10, param1=100, param2=15, minRadius=rayon_min, maxRadius=rayon_max) # un peu lent + + # Rapide mais avec beaucoup de faux positif -> contrôle cinématique + cercles = cv.HoughCircles(cam_gray, cv.HOUGH_GRADIENT, 1.5, rows/10, param1=100, param2=15, minRadius=rayon_min, maxRadius=rayon_max) + # Archives ... # cercles = cv.HoughCircles(cam_gray, cv.HOUGH_GRADIENT, 1, rows / 8, param1=30, param2=15, minRadius=rayon_min, maxRadius=rayon_max) # cercles = cv.HoughCircles(cam_gray, cv.HOUGH_GRADIENT, 1.5, rows / 8, param1=100, param2=30, minRadius=rayon_min, maxRadius=rayon_max) # cercles = cv.HoughCircles(cam_gray, cv.HOUGH_GRADIENT, 1, rows / 8, param1=100, param2=30, minRadius=5, maxRadius=10) - # Un peu lent, fiable -> bien pour la bille de 9 mm - cercles = cv.HoughCircles(cam_gray, cv.HOUGH_GRADIENT, 1, rows/10, param1=100, param2=15, minRadius=rayon_min, maxRadius=rayon_max) # un peu lent - - # Rapide mais avec beaucoup de faux positif -> bien pour la bille de 4 mm avec le contrôle cinématique - # cercles = cv.HoughCircles(cam_gray, cv.HOUGH_GRADIENT, 1.5, rows/10, param1=100, param2=15, minRadius=rayon_min, maxRadius=rayon_max) # Dessin de la zone de détection cv.rectangle(cam_img, (cadre_x0, cadre_y0), (cadre_x1, cadre_y1), (0, 0, 255), 2) # Contour du cadre de détection diff --git a/labyrinthe/6-jumeaux/test/cam_couleur-test.py b/labyrinthe/6-jumeaux/test/cam_couleur-test.py index 93577d3..2f2ff61 100644 --- a/labyrinthe/6-jumeaux/test/cam_couleur-test.py +++ b/labyrinthe/6-jumeaux/test/cam_couleur-test.py @@ -80,7 +80,7 @@ lower_limit, upper_limit = get_color_limits(color=rouge) while cam.isOpened(): cam_actif, cam_img_orig = cam.read() - cam_img = cv.rotate(cam_img_orig, cv.ROTATE_90_COUNTERCLOCKWISE) + cam_img = cv.rotate(cam_img_orig, cv.ROTATE_90_CLOCKWISE) cam_hsv = cv.cvtColor(cam_img, cv.COLOR_BGR2HSV) cam_mask=cv.inRange(cam_hsv, lower_limit, upper_limit)