Änderungen

Aus Hackerspace Ffm
Wechseln zu: Navigation, Suche

OpenCV mit Python

6.299 Byte hinzugefügt, 18:52, 31. Mai 2019
/* OpenCV Cheats */
= Installation =
Nach Update auf Pycharm 2019.1 kann es zu Problemen mit ALtGr+[ etc. kommen
 
Workaround: In PyCharm click Ctrl + Shift + A. Then write registry and click on it. Find actionSystem.fix.alt.gr and uncheck it.
== Raspberry Pi ==
** <code>import cv2</code>
** <code>quit()</code>
 
Wenn beim import cv2 Fehlermeldungen angezeigt werden, hilft es folgende libs zu installieren:
<pre>
sudo apt-get install libcblas-dev
sudo apt-get install libhdf5-dev
sudo apt-get install libhdf5-serial-dev
sudo apt-get install libatlas-base-dev
sudo apt-get install libjasper-dev
sudo apt-get install libqtgui4
sudo apt-get install libqt4-test
</pre>
 
* Tipp: Als IDE unter Raspbian für Python3 ist '''Thonny''' ein Versuch wert:
** Installation am besten via pip: <code>sudo pip3 install thonny</code>
** Füge am Ende der Datei eine Zeile mit dem Inhalt <code>bcm2835-v4l2</code> ein, Datei dann mit STRG+o speichern, den Editor mit STRG+x verlassen, das System neu starten
** Danach sollte das Kommando <code>ls /dev/video0</code> eine Device-Datei finden und keinen Fehler ausgeben. Wenn nicht, hilft es evtl. im obigen Schritt noch vor die '''bcm2835-v4l2'''-Zeile eine Zeile mit folgendem Inhalt einzufügen: <code>v4l2_common</code> (auch hier nach neu booten). Bei mir war das allerdings nicht nötig.
* Jetzt kann alles zusammen getestet werden, in dem das Skript im Abschnitt [[Abschnitt OpenCV_mit_Python#Testen_der_Kamera_unter_Python-OpenCV]] auf der Konsole oder z.B. in Thonny gestartet wird. Es sollte ein Fenster mit dem Kamerabild in Graustufen anzeigen.
== Windows (und ggf auch Mac/Linux) via PyCharm ==
* Installiere Python3 von Python.org: '''Wichtig:'''
** Per Rechtsklick als Admin installieren
Es sollte das Videobild in Graustufen angezeigt werden, im aktiven Kamerabildfenster "ESC" drücken, um das Program ordentlich zu beenden.
 
== RAW-Zugriff auf die Raspberry Pi Kamera ==
Mit dem folgenden Skript kann ohne V4L2-Treiber auf die Raspberry Pi Kamera zugegriffen werden. Evtl. ermöglicht das auch feinere Einstellungsmöglichkeiten der Kamera wie z.B. Belichtungszeit etc.
<pre>
# OpenCV camera test special for Raspberry Pi
# import the necessary packages
from picamera.array import PiRGBArray
from picamera import PiCamera
import time
import cv2
import numpy as np
 
# initialize the camera and grab a reference to the raw camera capture
camera = PiCamera()
camera.resolution = (640, 480)
camera.framerate = 32
camera.rotation = 0
rawCapture = PiRGBArray(camera, size=camera.resolution)
 
# allow the camera to warmup
time.sleep(1)
 
# capture frames from the camera
for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
# grab the raw NumPy array representing the image, then initialize the timestamp
# and occupied/unoccupied text
image = frame.array
# show the frame
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv2.imshow("Hit ESC to end", gray.astype(np.uint8))
# clear the stream in preparation for the next frame
rawCapture.truncate(0)
 
# if the `q` or ESC key was pressed, break from the loop
key = cv2.waitKey(1) & 0xFF
if key == ord("q") or key == 27:
break
 
cv2.destroyAllWindows()
camera.close()
</pre>
 
Es sollte das Videobild in Graustufen angezeigt werden, im aktiven Kamerabildfenster "ESC" drücken, um das Program ordentlich zu beenden.
 
= OpenCV Cheats =
* Tutorials hier: https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_tutorials.html
* Buntes Bild in Graustufen umwandeln: <code>gray = cv2.cvtColor(bild,cv2.COLOR_BGR2GRAY)</code>
* Graustufen Bild in Buntbild umwandeln: <code>bunt = cv2.cvtColor(gray,cv2.COLOR_GRAY2BGR)</code> (es bleibt Grau, kann dann aber eingefärbt werden)
* Kasten in ein Bild malen: <code>cv2.rectangle(bild, (x0,y0), (x1,y1), (b,g,r), rahmendicke)</code>
* Text ins Bild malen: <code>cv2.putText(bild, "Hallo", (10,400), cv2.FONT_HERSHEY_PLAIN, 1, (255,0,255))</code> (Größerer Font: cv2.FONT_HERSHEY_SIMPLEX)
* Bildbereich kopieren: <code>block = bild[y0:y1, x0:x1]</code>
* Bildbereich woanders einfügen (Größe muss genau passen!): <code>bild[y0:y1, x0:x1] = block</code>
* Alle Farbkomponenten eines Pixels ändern: <code>bild[y,x] = [b,g,r]</code>
* Nur eine Farbkomponente ändern (hier g = Index 1 da Reihenfolge BGR): <code>bild[x,y,1] = 255</code>
* 8-Bit Farbkomponenten holen: <code>bild.astype(np.uint8)</code> (falls man mal mit float oder so gerechnet hat)
* ArUco Marker (QR-Code ähnlich). http://www.philipzucker.com/aruco-in-opencv/
 
== Maus-Events ==
Maus-Events können über ein Callback verarbeitet werden, OpenCV möchte aber wissen, welches der "imshow"-Fenster dafür herangezogen werden soll. Dazu muss das Fenster am Start einmal explizit mit einem Namen versehen werden.
 
<pre>
mx = 10
my = 10
 
def mouseEvent(event,x,y,flags,param):
global mx,my
mx = x
my = y
#print(x, y)
 
cv.namedWindow("Window1")
cv.setMouseCallback("Window1", mouseEvent)
</pre>
 
== Bar/QR Codes Lesen ==
Eine funktionierende Library dafür ist "zbar" (mit PIP als "pyzbar" zu finden).
Allerdings benötigt die Library noch "PIL" (Python Imaging Library), die aktuell als "PILLOW" weitergeführt wird.
Um die Examples von "zbar" also ausführen zu können muss neben "PILLOW" noch der Wrapper "PILLOW - PIL" installiert werden.
 
<pre>
decoded = pyzbar.decode(im)
 
for obj in decoded:
print('Typ : ', obj.type)
print('Wert: ', obj.data, '\n')
</pre>
 
[[Datei:OpencvWorkshopQRCodeRecognition.jpg]]
 
== Optical Flow ==
Beispiel Code um features zu verfolgen, aka optical flow.
Code funktioniert unter OpenCV Version 3.4.4
 
[[Datei:OpencvOpticalFlowPICam.zip]]
 
[[Datei:OpencvOpticalFlowUSBCam.zip]]
 
[[Datei:OpencvWorkshopOpticalFlow.jpg|400px]]
 
== ArUco - Pose Estimation ==
Findet den ArUco Marker und seine Position sowie Orientierung im Raum.<br>
Über eine Distanzfunktion kann dann z.B. die Entfernung des Markermittelpunktes zur Kamera ermittelt werden. Dieser wird in cm unten links angezeigt.
 
<pre>
import numpy as np
import cv2
import cv2.aruco as aruco
 
cap = cv2.VideoCapture(0)
aruco_dict = aruco.Dictionary_get(aruco.DICT_6X6_250)
parameters = aruco.DetectorParameters_create()
 
while(True):
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
corners, ids, rejectedImgPoints = aruco.detectMarkers(gray, aruco_dict, parameters=parameters)
gray = aruco.drawDetectedMarkers(gray, corners, ids)
 
mtx = np.array([[5.3434144579284975e+02, 0., 3.3915527836173959e+02],
[0., 5.3468425881789324e+02, 2.3384359492532246e+02],
[0., 0., 1.]], np.float)
dist = np.array([-2.8832098285875657e-01, 5.4107968489116441e-02,
1.7350162244695508e-03, -2.6133389531953340e-04,
2.0411046472667685e-01], np.float)
 
if ids != None: # if aruco marker detected
rvec, tvec, objp = aruco.estimatePoseSingleMarkers(corners, 3.5, mtx, dist) # For a single marker
aruco.drawDetectedMarkers(gray, corners, ids, (0, 255, 0))
aruco.drawAxis(gray, mtx, dist, rvec, tvec, 10)
print(tvec[0][0])
distance = round( np.linalg.norm(tvec[0][0]), 2)
cv2.putText(gray, str( distance ) + " cm", (10, 400), cv2.FONT_HERSHEY_PLAIN, 1, (255, 0, 255))
 
cv2.imshow('frame',gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
 
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
</pre>
[[Datei:ArUco_PoseEstimation.png|400px]]
1.932
Bearbeitungen