Pagina 1 di 2

Implementazione robot su 4 ruote con telecamera ed OpenCV

MessaggioInviato: 16 mar 2025, 18:47
da alien75
Salve, sto cercando di implementare un robot su 4 ruote comandato da un Raspberry pi 3B collegatoa telecamera e getito da un programma basato su opencv.
Lo scopo del robot per il momento è quello di distinguere la differenza tra una porta chiusa o aperta;
in questo secondo caso deve oltrepassarla oppure fermarsi se chiusa.
Sto studiando il tutorial delle opencv. Ho scritto del codice che legge dalla telecamera attraverso del codice python, passo sucessivo definire i contorni della porta per poi definire lo sfondo.
Riporto il codice e spiego velocemente il problema:
Codice: Seleziona tutto
import numpy as np
import cv2 as cv

cap = cv.VideoCapture(0)
if not cap.isOpened():
    print("Cannot open camera")
    exit()
while True:
    # Capture frame-by-frame
    ret, frame = cap.read()
   
    # if frame is read correctly ret is True
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
    # Our operations on the frame come here
    gray = cv.cvtColor(frame, cv.COLOR_BGRA2RGBA)
    ret,thresh = cv.threshold(gray,127,255,0)
    contours,hierarchy = cv.findContours(thresh, 1, 2)

    cv.imshow('frame', contours)
   
    if cv.waitKey(1) == ord('q'):
        break

cap.release()
cv.destroyAllWindows()



Se lancio il codice con "python Video.py" ottengo il seguente errore dall' interprete:

Codice: Seleziona tutto
[ WARN:0] global ./modules/videoio/src/cap_gstreamer.cpp (1100) open OpenCV | GStreamer warning: Cannot query video position: status=0, value=-1, duration=-1
Traceback (most recent call last):
  File "/home/fabio/Scrivania/Video.py", line 19, in <module>
    contours,hierarchy = cv.findContours(thresh, 1, 2)
cv2.error: OpenCV(4.5.4) ./modules/imgproc/src/contours.cpp:195: error: (-210:Unsupported format or combination of formats) [Start]FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL otherwise supports CV_32SC1 images only in function 'cvStartFindContours_Impl'


Sto cercando di dare in pasto l'immagine a colori della telecamera a cv.threshold() poi sucessivamente a cv.findContours() ma mi da errore e non capisco perché: forse incompatibilità degli oggetti in questione.
Scusate l'ignoranza delle opencv ma sono agli inizi.
Mi potete aiutare?

Re: Implementazione robot su 4 ruote con telecamera ed OpenC

MessaggioInviato: 16 mar 2025, 22:13
da angus
Sembra che non gli piaccia l'immagine a 3 canali per rilevare i contorni.
proverei con: COLOR_BGRA2GRAY invece che COLOR_BGRA2RGBA
e con qualche altra modifica:

Codice: Seleziona tutto
import numpy as np
import cv2 as cv

cap = cv.VideoCapture(0)
if not cap.isOpened():
    print("Cannot open camera")
    exit()
while True:
    # Capture frame-by-frame
    ret, frame = cap.read()
   
    # if frame is read correctly ret is True
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
    # Our operations on the frame come here
    gray = cv.cvtColor(frame, cv.COLOR_BGRA2GRAY)
    ret,thresh = cv.threshold(gray,127,255,0)
    contours,hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
    cv.drawContours(frame, contours, -1, (0, 255, 0), 3)

    cv.imshow('frame', frame)
   
    if cv.waitKey(1) == ord('q'):
        break

cap.release()
cv.destroyAllWindows()

Re: Implementazione robot su 4 ruote con telecamera ed OpenC

MessaggioInviato: 17 mar 2025, 10:05
da luxinterior
Non è il mio mondo perché utilizzo (a fatica) open_cv su ESP32 e non rpy
Secondo me dovresti verificare il formato dell'immagine che ottieni dalla telecamera. Il messagigo dice che vuole CV_8UC1 un canale 8bit unsigned immagine a scala di grigi con 8bit/pixel
Puoi applicare le trasformazioni suggerite da angus qui sopra oppure configurare la telecamera per fornire l'immagine richiesta. Fai attenzione che se la telecamera ti fornisc eimmagien compressa jpeg devi prima riportarla a RGB o cchi per lui e poi elaborarla. Il messaggio è verifica qual è il dato di partenza poi si cerca la procedura corretta.

Re: Implementazione robot su 4 ruote con telecamera ed OpenC

MessaggioInviato: 18 mar 2025, 5:44
da alien75
Grazie Angus; funziona.
Ottengo le linee verdi dei contorni.
Ora devo far si che il sistema "veda" la porta ma col codice seguente vede solo i primi piani in movimento: quando l'immagine si ferma il primo piano sparisce:
Codice: Seleziona tutto
from __future__ import print_function
import cv2 as cv
import argparse

parser = argparse.ArgumentParser(description='')
parser.add_argument('--input', type=str, help='', default='vtest.avi')
parser.add_argument('--algo', type=str, help='Background subtraction method (KNN, MOG2).', default='MOG2')
args = parser.parse_args()


if args.algo == 'MOG2':
    backSub = cv.createBackgroundSubtractorMOG2()
else:
    backSub = cv.createBackgroundSubtractorKNN()



capture = cv.VideoCapture(0)
if not capture.isOpened():
    print('Unable to open camera')
    exit(0)


while True:
    ret, frame = capture.read()
    if frame is None:
        break

   
    fgMask = backSub.apply(frame)
   

   
    cv.rectangle(frame, (10, 2), (100,20), (255,255,255), -1)
    cv.putText(frame, str(capture.get(cv.CAP_PROP_POS_FRAMES)), (15, 15),
               cv.FONT_HERSHEY_SIMPLEX, 0.5 , (0,0,0))
   

   
    cv.imshow('Frame', frame)
    cv.imshow('FG Mask', fgMask)
   

    keyboard = cv.waitKey(30)
    if keyboard == 'q' or keyboard == 27:
        break


Che modo c'è per far si che il sistema "veda" la porta?
Forse cv.ForeGround()?

Ho inserito questo codice di esempio modificato per poter fargli vedere il primopiano ma non so se possa servire:

Codice: Seleziona tutto
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
#img = cv.imread('messi5.jpg')
cap = cv.VideoCapture(0)
if not cap.isOpened():
    print("Cannot open camera")
    exit()
ret, frame = cap.read()
assert frame is not None, "file could not be read, check with os.path.exists()"
mask = np.zeros(frame.shape[:2],np.uint8)
bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)
rect = (50,50,450,290)
cv.grabCut(frame,mask,rect,bgdModel,fgdModel,5,cv.GC_INIT_WITH_RECT)
mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
frame = frame*mask2[:,:,np.newaxis]
plt.imshow(frame),plt.colorbar(),plt.show()

Re: Implementazione robot su 4 ruote con telecamera ed OpenC

MessaggioInviato: 20 mar 2025, 20:46
da alien75
Ho scaricato questo codice dal sito del tutorial ed ho modificato un po per far si che legga da usbcamera e non da file immagine:
Codice: Seleziona tutto
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
#img = cv.imread('messi5.jpg')
#assert img is not None, "file could not be read, check with os.path.exists()"
cap = cv.VideoCapture(0)
if not cap.isOpened():
    print("Cannot open camera")
    exit()
while True:
    # Capture frame-by-frame
    ret, frame = cap.read()
    # if frame is read correctly ret is True
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
    mask = np.zeros(frame.shape[:2],np.uint8)
    bgdModel = np.zeros((1,65),np.float64)
    fgdModel = np.zeros((1,65),np.float64)
    rect = (50,50,450,290)
    cv.grabCut(frame,mask,rect,bgdModel,fgdModel,5,cv.GC_INIT_WITH_RECT)
    mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
    frame = frame*mask2[:,:,np.newaxis]
    plt.imshow(frame),plt.colorbar(),plt.show()


Ma all'avvio ottengo il seguente messaggio di errore:
Codice: Seleziona tutto
module that was compiled using NumPy 1.x cannot be run in
NumPy 2.2.4 as it may crash. To support both 1.x and 2.x
versions of NumPy, modules must be compiled with NumPy 2.0.
Some module may need to rebuild instead e.g. with 'pybind11>=2.12'.

If you are a user of the module, the easiest solution will be to
downgrade to 'numpy<2' or try to upgrade the affected module.
We expect that some modules will need time to support NumPy 2.

Traceback (most recent call last):  File "/home/fabio/Scrivania/prova.py", line 2, in <module>
    import cv2 as cv
AttributeError: _ARRAY_API not found
Traceback (most recent call last):
  File "/home/fabio/Scrivania/prova.py", line 2, in <module>
    import cv2 as cv
ImportError: numpy.core.multiarray failed to import


sembra che non gli vada a genio o ci sia problemi con cv2 già installate.
Cosa può essere?

Re: Implementazione robot su 4 ruote con telecamera ed OpenC

MessaggioInviato: 21 mar 2025, 1:18
da xyz
OpenCV è compilato con una versione diversa rispetto a quella installata di Numpy. Aggiorna la tua installazione in modo che siano compatibili tra loro.

Re: Implementazione robot su 4 ruote con telecamera ed OpenC

MessaggioInviato: 21 mar 2025, 8:10
da alien75
Ho scritto:
Codice: Seleziona tutto
pip3 install --upgrade python-opencv


ed ottengo:
Codice: Seleziona tutto
ERROR: Could not find a version that satisfies the requirement python-opencv (from versions: none)
ERROR: No matching distribution found for python-opencv


perché?

Ora do:
Codice: Seleziona tutto
pip3 install --upgrade opencv-python


Funziona.

Ho avviato il codice di cui sopra e mi da:
Codice: Seleziona tutto
A module that was compiled using NumPy 1.x cannot be run in
NumPy 2.2.4 as it may crash. To support both 1.x and 2.x
versions of NumPy, modules must be compiled with NumPy 2.0.
Some module may need to rebuild instead e.g. with 'pybind11>=2.12'.

If you are a user of the module, the easiest solution will be to
downgrade to 'numpy<2' or try to upgrade the affected module.
We expect that some modules will need time to support NumPy 2.

Traceback (most recent call last):  File "/home/fabio/Scrivania/prova.py", line 2, in <module>
    import cv2 as cv
AttributeError: _ARRAY_API not found
Traceback (most recent call last):
  File "/home/fabio/Scrivania/prova.py", line 2, in <module>
    import cv2 as cv
ImportError: numpy.core.multiarray failed to import

Re: Implementazione robot su 4 ruote con telecamera ed OpenC

MessaggioInviato: 21 mar 2025, 17:20
da alien75
Ho aggiornato le opencv ed il codice funziona.
Codice:
Codice: Seleziona tutto
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
while True:
    cap = cv.VideoCapture(0)
    if not cap.isOpened():
        print("Cannot open camera")
        exit()
    # Capture frame-by-frame
    ret, frame = cap.read()
    mask = np.zeros(frame.shape[:2],np.uint8)
    bgdModel = np.zeros((1,65),np.float64)
    fgdModel = np.zeros((1,65),np.float64)
    rect = (50,50,450,290)
    cv.grabCut(frame,mask,rect,bgdModel,fgdModel,5,cv.GC_INIT_WITH_RECT)
    mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
    frame = frame*mask2[:,:,np.newaxis]
    plt.imshow(frame),plt.colorbar(),plt.show()


Il sistema rileva come primo piano un comodino.

Re: Implementazione robot su 4 ruote con telecamera ed OpenC

MessaggioInviato: 21 mar 2025, 20:30
da alien75
alien75 ha scritto:Ho aggiornato le opencv ed il codice funziona.
Codice:
Codice: Seleziona tutto
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
while True:
    cap = cv.VideoCapture(0)
    if not cap.isOpened():
        print("Cannot open camera")
        exit()
    # Capture frame-by-frame
    ret, frame = cap.read()
    mask = np.zeros(frame.shape[:2],np.uint8)
    bgdModel = np.zeros((1,65),np.float64)
    fgdModel = np.zeros((1,65),np.float64)
    rect = (50,50,450,290)
    cv.grabCut(frame,mask,rect,bgdModel,fgdModel,5,cv.GC_INIT_WITH_RECT)
    mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
    frame = frame*mask2[:,:,np.newaxis]
    plt.imshow(frame),plt.colorbar(),plt.show()


Il sistema rileva come primo piano un comodino.


Adesso devo far "vedere" al sistema una porta chiusa o aperta, come si fa?

Re: Implementazione robot su 4 ruote con telecamera ed OpenC

MessaggioInviato: 21 mar 2025, 22:06
da gvee
Devi allenare l'algoritmo per una classificazione binaria (porta aperta/chiusa).

Cerca "logistic regression". Esistono molti esempi in rete che puoi modificare ed applicare al tuo caso, p.e. (non l'ho provato ma direi che è preso dall'esempio del corso di Andrew NG con DeepLearning.AI):

https://goodboychan.github.io/python/co ... twork.html

Io proverei questo approccio.