kivyblocks/kivyblocks/kivycamera.py
2021-08-15 16:57:20 +08:00

89 lines
2.7 KiB
Python

import os
from kivy.app import App
from kivy.uix.image import Image
from kivy.clock import Clock
from kivy.graphics.texture import Texture
from kivy.factory import Factory
import cv2
facefilepath=os.path.dirname(cv2.__file__)
facepattern = '%s/%s' % (facefilepath, \
'data/haarcascade_frontalface_default.xml')
def set_res(cap, x,y):
cap.set(cv2.CAP_PROP_FRAME_WIDTH, int(x))
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, int(y))
return cap.get(cv2.CAP_PROP_FRAME_WIDTH),cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
class KivyCamera(Image):
def __init__(self, device=0, fps=25.0, face_detect=False, **kwargs):
print('KivyCamera inited')
self.update_task = None
self.capture = None
super(KivyCamera, self).__init__(**kwargs)
self.capture = cv2.VideoCapture(device)
self.face_detect = face_detect
self.device = device
self.faceCascade = None
if face_detect:
self.faceCascade = cv2.CascadeClassifier(facepattern)
if not self.faceCascade:
print('self.faceCascade is None')
self.update_task = Clock.schedule_interval(self.update, 1.0 / fps)
def on_size(self,o,size):
if self.capture:
self.capture.release()
self.capture = cv2.VideoCapture(self.device)
size = set_res(self.capture,self.width,self.height)
print(size)
def add_face_detect(self,frame):
frameGray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = self.faceCascade.detectMultiScale(frameGray,
scaleFactor = 1.2, minNeighbors = 5)
print('add_face_detect(): faces=',faces)
# THIS LINE RAISE ERROR
# faces = self.faceCascade.detectMultiScale(frameGray, 1.1, 4)
for (x, y, w, h) in faces: # added
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
return frame
def update(self, dt):
ret, frame = self.capture.read()
if ret:
if self.width / self.height > frame.shape[1] / frame.shape[0]:
fx = fy = self.height / frame.shape[0]
else:
fx = fy = self.width / frame.shape[1]
frame = cv2.resize(frame, None,
fx=fx, fy=fy,
interpolation=cv2.INTER_LINEAR)
if self.faceCascade:
try:
frame = self.add_face_detect(frame)
except Exception as e:
print('Error, e=',e)
pass
# convert it to texture
buf1 = cv2.flip(frame, 0)
buf = buf1.tostring()
image_texture = Texture.create(
size=(frame.shape[1], frame.shape[0]), colorfmt='bgr')
image_texture.blit_buffer(buf, colorfmt='bgr', bufferfmt='ubyte')
# display image from the texture
self.texture = image_texture
else:
self.update_task.cancel()
print('failed to read from capture')
def __del__(self):
if self.update_task:
self.update_task.cancel()
self.update_task = None
# self.cupture.close()