Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Implementazione robot su 4 ruote con telecamera ed OpenCV

Linguaggi e sistemi

Moderatori: Foto UtentePaolino, Foto Utentefairyvilje

0
voti

[1] Implementazione robot su 4 ruote con telecamera ed OpenCV

Messaggioda Foto Utentealien75 » 16 mar 2025, 18:47

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?
Avatar utente
Foto Utentealien75
1 1 4 8
Sostenitore
Sostenitore
 
Messaggi: 588
Iscritto il: 31 lug 2011, 14:08

0
voti

[2] Re: Implementazione robot su 4 ruote con telecamera ed OpenC

Messaggioda Foto Utenteangus » 16 mar 2025, 22:13

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()
in /dev/null no one can hear you scream
Avatar utente
Foto Utenteangus
8.475 4 6 9
G.Master EY
G.Master EY
 
Messaggi: 4168
Iscritto il: 20 giu 2008, 17:25

0
voti

[3] Re: Implementazione robot su 4 ruote con telecamera ed OpenC

Messaggioda Foto Utenteluxinterior » 17 mar 2025, 10:05

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.
Avatar utente
Foto Utenteluxinterior
4.311 3 4 9
Master EY
Master EY
 
Messaggi: 2690
Iscritto il: 6 gen 2016, 17:48

0
voti

[4] Re: Implementazione robot su 4 ruote con telecamera ed OpenC

Messaggioda Foto Utentealien75 » 18 mar 2025, 5:44

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()
Avatar utente
Foto Utentealien75
1 1 4 8
Sostenitore
Sostenitore
 
Messaggi: 588
Iscritto il: 31 lug 2011, 14:08

0
voti

[5] Re: Implementazione robot su 4 ruote con telecamera ed OpenC

Messaggioda Foto Utentealien75 » 20 mar 2025, 20:46

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?
Avatar utente
Foto Utentealien75
1 1 4 8
Sostenitore
Sostenitore
 
Messaggi: 588
Iscritto il: 31 lug 2011, 14:08

0
voti

[6] Re: Implementazione robot su 4 ruote con telecamera ed OpenC

Messaggioda Foto Utentexyz » 21 mar 2025, 1:18

OpenCV è compilato con una versione diversa rispetto a quella installata di Numpy. Aggiorna la tua installazione in modo che siano compatibili tra loro.
Avatar utente
Foto Utentexyz
6.864 2 4 6
G.Master EY
G.Master EY
 
Messaggi: 1778
Iscritto il: 5 dic 2009, 18:37
Località: Italy Turin

0
voti

[7] Re: Implementazione robot su 4 ruote con telecamera ed OpenC

Messaggioda Foto Utentealien75 » 21 mar 2025, 8:10

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
Avatar utente
Foto Utentealien75
1 1 4 8
Sostenitore
Sostenitore
 
Messaggi: 588
Iscritto il: 31 lug 2011, 14:08

0
voti

[8] Re: Implementazione robot su 4 ruote con telecamera ed OpenC

Messaggioda Foto Utentealien75 » 21 mar 2025, 17:20

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.
Avatar utente
Foto Utentealien75
1 1 4 8
Sostenitore
Sostenitore
 
Messaggi: 588
Iscritto il: 31 lug 2011, 14:08

0
voti

[9] Re: Implementazione robot su 4 ruote con telecamera ed OpenC

Messaggioda Foto Utentealien75 » 21 mar 2025, 20:30

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?
Avatar utente
Foto Utentealien75
1 1 4 8
Sostenitore
Sostenitore
 
Messaggi: 588
Iscritto il: 31 lug 2011, 14:08

0
voti

[10] Re: Implementazione robot su 4 ruote con telecamera ed OpenC

Messaggioda Foto Utentegvee » 21 mar 2025, 22:06

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.
Avatar utente
Foto Utentegvee
1.475 5 7
Sostenitore
Sostenitore
 
Messaggi: 525
Iscritto il: 11 feb 2018, 20:34

Prossimo

Torna a PC e informatica

Chi c’è in linea

Visitano il forum: Nessuno e 22 ospiti