Я создал видеопоток, который принимает данные с камеры, рисует прямоугольники на лицах и рисует данные о времени и погоде в верхней части кадра. Этот кадр показан в приложении wxPython. Большую часть времени он зависает после нескольких секунд работы. Если он не останавливается при запуске, он часто зависает и вылетает при перемещении в кадре, снятом камерой. Можно ли этого избежать или процесс распознавания лица слишком сложен для запуска Python? код:
import wx
from PIL import Image
import cv2
import numpy as np
import requests
import time
import json
from datetime import datetime
SIZE = (1280, 720)
CapDev = cv2.VideoCapture(0)
# THIS PART HAS BEEN DELETED, CONTAINED PRIVATE API KEYS
req = None
appid = ''
api_url = ''
city_id =
haar_cascade_face = cv2.CascadeClassifier('data/haarcascade_frontalface_default.xml')
starttime = time.time()
dispcount = 0
size = CapDev.read()[1].shape[:2]
size = size[:2]
size = size[::-1]
print(size)
font = cv2.FONT_HERSHEY_SIMPLEX
white = (255, 255, 255)
left_bot_text = (0, size[1] - 50)
left_top_text = (0, 25)
def get_image():
global req, appid, api_url, city_id, font, size
frame = CapDev.read()[1]
if not req:
req = [requests.get(url=api_url, params=dict(q='Ghent,be', APPID=appid)), time.time()]
req = getweatherinfo(req)
weatherinfo = processweatherinfo(req)
localtime = gettime()
# detecting faces using opencv2 cascades
frame = detect_faces(haar_cascade_face, frame)
# drawing weather info + rectangle around it
cv2.putText(frame, weatherinfo, left_top_text, font, 1, white, 2, cv2.LINE_AA)
rightbot, thikness = cv2.getTextSize(weatherinfo, font, 1, 2)
cv2.rectangle(frame, (rightbot[0], rightbot[1]+thikness+10), (0, 0), white, 2)
# drawing the current time + rectangle around it
cv2.putText(frame, localtime, left_bot_text, font, 1, white, 2, cv2.LINE_AA)
rightbot2, thikness2 = cv2.getTextSize(localtime, font, 1, 2)
cv2.rectangle(frame, (rightbot2[0], size[1]-50 + thikness2), (0, size[1]-80), white, 2)
totimg = frame
totimage = convertToRGB(totimg)
image = Image.fromarray(totimage)
return image
def getweatherinfo(weatherreq):
if int(time.time() - weatherreq[1]) > 1:
wetreq = [requests.get(url=api_url, params=dict(q='Ghent', APPID=appid)), time.time()]
print('New Request ')
else:
wetreq = weatherreq
return wetreq
def convertToRGB(image):
return cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
def detect_faces(cascade, test_img, scaleFactor = 1.1):
img_copy = test_img.copy()
gray_img = cv2.cvtColor(img_copy, cv2.COLOR_BGR2GRAY)
faces_rects = cascade.detectMultiScale(gray_img, scaleFactor = scaleFactor, minNeighbors = 5)
for (x, y, w, h) in faces_rects:
cv2.rectangle(img_copy, (x, y), (x + w, y + h), (255, 0, 0), 2)
return img_copy
def processweatherinfo(reqresp):
datastore = json.loads(reqresp[0].text)
global starttime
global dispcount
weather = datastore['weather'][0]['main'] + ': ' + datastore['weather'][0]['description']
temp = str(datastore['main']['temp']) + 'K, '+str(round(float(datastore['main']['temp'])-273.15, 2))+" deg. Celsius"
wind = 'wind speed ' + str(datastore['wind']['speed']) + 'm/s' # + str(datastore['wind']['deg']) + ' degrees'
cycle = [weather, temp, wind]
if starttime-time.time() < -3 and dispcount != 2:
dispcount += 1
starttime = time.time()
elif starttime - time.time() < -3 and dispcount == 2:
dispcount = 0
starttime = time.time()
return cycle[dispcount]
def unixtodatetime(unix_stamp):
dt_object = datetime.fromtimestamp(unix_stamp)
dt_object = str(dt_object).split()
return dt_object[1], dt_object[0]
def gettime():
timestamp = unixtodatetime(time.time())[0]
return timestamp[:11]
def pil_to_wx(image):
width, height = image.size
buffer = image.convert('RGB').tobytes()
bitmap = wx.Bitmap.FromBuffer(width, height, buffer)
return bitmap
class HUDPanel(wx.Panel):
def __init__(self, parent):
super(HUDPanel, self).__init__(parent, -1)
self.SetInitialSize(size)
self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
self.Bind(wx.EVT_PAINT, self.on_paint)
self.update()
def update(self):
self.Refresh()
self.Update()
wx.CallLater(15, self.update)
def create_bitmap(self):
image = get_image()
bitmap = pil_to_wx(image)
return bitmap
def on_paint(self, event):
bitmap = self.create_bitmap()
dc = wx.AutoBufferedPaintDC(self)
dc.DrawBitmap(bitmap, 0, 0)
class ExtraPanel(wx.Panel):
def __init__(self, parent):
super(ExtraPanel, self).__init__(parent, -1)
self.SetInitialSize(size)
self.SetBackgroundColour(wx.SystemSettings.GetColour(0))
My_Button = wx.Button(self, label="STOP")
My_Button.Bind(wx.EVT_BUTTON, self.stop_on_press)
def stop_on_press(self, event):
print("TestButton was used")
wx.Exit()
class Frame(wx.Frame):
def __init__(self):
style = wx.DEFAULT_FRAME_STYLE & ~wx.RESIZE_BORDER & ~wx.MAXIMIZE_BOX
super(Frame, self).__init__(None, -1, 'Camera Viewer', style=style)
my_sizer = wx.BoxSizer(wx.HORIZONTAL)
campanel = HUDPanel(self)
campanel.SetSize(size)
my_sizer.Add(campanel, wx.CENTER, 0)
widgetpanel = ExtraPanel(self)
widgetpanel.SetSize(size)
my_sizer.Add(widgetpanel, 0, wx.ALL | wx.CENTER, 5)
self.SetSizer(my_sizer)
self.SetSize((size[0]*2,size[1]))
def main():
app = wx.App()
frame = Frame()
frame.Show()
app.MainLoop()
if __name__ == '__main__':
main()
Извините за грязный код. Любые улучшения в кодировании / подсказка для перестановки кода приветствуются