89 lines
2.7 KiB
Python
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()
|
|
|