Pilditöötlus OpenCV abil
From ICO wiki
Andmete kodeerimise praktikum
Andmete kodeerimise loeng päevõppes toimub 20. aprillil, esitlus siin: https://docs.google.com/presentation/d/1QV_IMOadIEUTBW7Laqw59j8J7Y8HKwvSDmP-swEEx0s
Prakikumis keskendume pilditöötlusele, et natukene aru saada mis moodi bitid/baidid liiguvad video ja pildifailides, selleks:
- Laadi alla Robotex 2016 testpäeva videofailid aadressilt https://owncloud.koodur.com/index.php/s/AGabLBFTL3xlDah
- Kasuta programmi toorikuna allpool olevat koodijuppi, salvesta see faili pildituvastus.py
- Käivita programm käsutealt: python pildituvastus.py failinimi.avi
- Püüa leida vastused järgnevatele küsimustele
Küsimused:
- Mis on kaadri (frame) eraldusvõime (resolution)?
- Mis piksliformaadis on cap.read() väljastatud kaader?
- Mis on kaadrisagedus (framerate)? Mis on ühe kaadri kuvamise aeg?
- Mis on kaadri suurus baitides?
- Mitu kaadrit on failis?
- Kui salvestada kõik kaadrid pakkimata kujul kettale, palju need ruumi võtaksid?
- Kui palju ruumi säästab video pakkimine?
Natuke koodi torkimist:
- Tee kaadriloendur türkiissiniseks https://en.wikipedia.org/wiki/Turquoise_(color)#Turquoise_Blue
- Kohenda koodi nii et tuvastataks pallid
- Täienda koodi et leitaks sinine värav
- Täienda koodi et leitaks kollane värav
- Saada oma vastused ja modifikatsioonidega programm lauri.vosandi@itcollege.ee aadressile ning märgi e-kirja teemaks "I027 Pildituvastus"
Lisaülesanded nuputamiskes, kui seni meeldis:
- Teades et kaamera on 22cm kõrgusel ning vaatenurk ülevalt horisondist alla on 72 kraadi arvuta välja palli kaugus ning kuva see palli kohal
- Leia palli nurk löögimehhanismist
- Leia palli vektor löögimehhanismi suhtes
- Millisele pallile kõige esimesena läheneda võiks praeguse kaadri järgi? Märgi ära see ekraanil.
Vihjed:
- Kasuta print lauset muutujate kuvamiseks terminalisse
- Kaader on sisuliselt mitmemõõteline massiiv
- Kes proovib oma Ubuntu masinas programmi käima ajada paigalda esmalt sõltuvused: apt install python-opencv python-numpy
# encoding: utf-8
import cv2
import os
import numpy as np
import sys
from time import sleep
try:
_, filename = sys.argv
except ValueError:
print("Anna argumendiks failinimi mida töödelda!")
sys.exit(255)
print "Avan faili:", filename
cap = cv2.VideoCapture(filename)
fps = cap.get(cv2.CAP_PROP_FPS)
success, frame = cap.read()
# Kommenteeri need välja ja uuri välja mis need teevad?
#print frame
#print frame.shape
#print frame.dtype
frameno = 0
while True:
# Loe ja paki lahti kaader failist
success, frame = cap.read()
frameno += 1
if not success:
break
# Piksliformaadi teisendus
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# Leia väärtuste vahemikku langevad pikslid
mask = cv2.inRange(frame, (100,0,0), (255,100,100))
#mask = cv2.inRange(hsv, (200,200,150), (255,255,255))
# Eemalda üksikud pikslid
mask = cv2.erode(mask, np.ones((2, 2)))
# Maski pikslite visualiseerimiseks lõika need välja esialgsest kaadrist
cutout = cv2.bitwise_and(frame, frame, mask=mask)
# Joonista kaadriloendur
cv2.putText(frame, "frame: %d" % frameno, (30, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 3)
# Moodusta kaadrite pinu
stacked = np.vstack([
frame,
np.stack([mask]*3, axis=2), # See on maski näitamiseks
cutout,
])
# Leia maskist kontuurid
_, contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Visualiseeri kontuurid mida ümbristeva ristküliku suurus on suurem kui 5x5 pisklit
for cnt in contours:
x,y,w,h = cv2.boundingRect(cnt)
if w > 5 and h > 5:
cv2.rectangle(stacked,(x,y),(x+w,y+h),(0,255,0),2)
cv2.putText(stacked, "pall", (x,y), cv2.FONT_HERSHEY_SIMPLEX, 1, (255,255,255), 3)
# Tee pilt pisemaks et ekraanile mahuks
zoomed = cv2.resize(stacked, None, fx=0.5,fy=0.5)
# Kuva kaader ekraanil
cv2.imshow("fov", zoomed)
# Oota natuke järgmise kaadri kuvamiseks
sleep(1.0/fps)
# Lõpeta programmi täitmine kui klaviatuuril vajutatakse Q nuppu
keycode = cv2.waitKey(1)
if keycode == ord('q'):
break
cap.release()