gpt4 book ai didi

python - 使用Qt Gui进行实时视频源的Opencv人脸检测速度较慢

转载 作者:行者123 更新时间:2023-12-02 17:01:09 25 4
gpt4 key购买 nike

我有一个项目,需要在gui中设计一个qt。该设计包含一个小部件,其中将使用live video feed从USB网络摄像头显示opencv。该项目将检测faces并识别它们,这意味着每个帧上都会进行大量处理。

为此,我创建了一个线程,该线程初始化相机并使用opencv从中获取帧。然后将所有帧放入队列中,然后通过函数update_frame读取此队列,该函数基本上在qt小部件上显示该帧。这很好,没有延迟。

update_frame函数内部,我添加了face detection,由于它执行起来非常慢。因此,我创建了另一个线程start_inferencing,该线程基本上从queue中读取帧,并在检测到面部之后将其再次放入另一个队列q2中,然后由update_frame读取,该队列显示但仍然响应非常慢。下面是代码:

q = queue.Queue()
q2 = queue.Queue()

def grab(cam, qu, width, height):
global running
capture = cv2.VideoCapture(cam)
capture.set(cv2.CAP_PROP_FRAME_WIDTH, width)
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, height)

while running:
frame = {}
capture.grab()
ret_val, img = capture.retrieve(0)
frame["img"] = img

if qu.qsize() < 100:
qu.put(frame)
else:
print(qu.qsize())

class Logic(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent)
self.setupUi(self)

set_initial_alert_temp()

self.window_width = self.ImgWidget.frameSize().width()
self.window_height = self.ImgWidget.frameSize().height()
self.ImgWidget = OwnImageWidget(self.ImgWidget)

self.timer = QtCore.QTimer(self)
self.timer.timeout.connect(self.update_frame)
self.timer.start(1)

self.outside_temp_text_box.setText(str(curr_temp_cel))

def update_frame(self):
if not q2.empty():
frame1 = q2.get()
img = frame1["img"]

img_height, img_width, img_colors = img.shape
scale_w = float(self.window_width) / float(img_width)
scale_h = float(self.window_height) / float(img_height)
scale = min([scale_w, scale_h])

if scale == 0:
scale = 1

img = cv2.resize(img, None, fx=scale, fy=scale, interpolation=cv2.INTER_CUBIC)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
height, width, bpc = img.shape
bpl = bpc * width
image = QtGui.QImage(img.data, width, height, bpl, QtGui.QImage.Format_RGB888)
self.ImgWidget.setImage(image)

def start_inferencing():
while True:
if not q.empty():
frame = q.get()
img = frame["img"]
face_bbox = face.detect_face(img)
if face_bbox is not None:
(f_startX, f_startY, f_endX, f_endY) = face_bbox.astype("int")
f_startX = f_startX + 10
f_startY = f_startY + 10
f_endX = f_endX - 10
f_endY = f_endY - 10
cv2.rectangle(img, (f_startX, f_startY), (f_endX, f_endY), (0, 255, 0), 2)

frame1 = {"img": img}

if q2.qsize() < 100:
q2.put(frame1)
else:
print(q2.qsize())

def main():

capture_thread = threading.Thread(target=grab, args=(0, q, 640, 480))
capture_thread.start()

infer_thread = threading.Thread(target=start_inferencing)
infer_thread.start()

app = QtWidgets.QApplication(sys.argv)
w = Logic(None)
w.setWindowTitle('Test')
w.show()
app.exec_()


main()

以下是代码中发生的情况的摘要:
camera -> frame -> queue.put                     # (reading frame from camera and putting it in queue)
queue.get -> frame -> detect face -> queue2.put # (getting frame from queue, detecting face in it and putting the updated frames in queue2)
queue2.get -> frame -> display it on qt widget # (getting frame from queue2 and display it on qt widget)

实时视频馈送缓慢的主要原因是因为在 grab函数中读取的帧无法更快地处理,因此 queue的大小不断增加,因此总体上变得很慢。我是否可以使用任何好的方法来检测并显示脸部而没有任何延迟。请帮忙。谢谢

最佳答案

队列会累积线程无法处理的帧。因此,根本没有办法处理它们。这就是队列在这里无用的原因。这里的工作时钟由到达的帧定义,每个帧都会生成事件,它可以在帧处理完成后在其自己的线程中工作(例如在处理线程中),处理线程生成另一个事件并在另一个线程中进行处理,例如在GUI线程中并向用户显示结果。

如果您强制需要一些缓冲区,请检查环形缓冲区是否具有有限的长度。

关于python - 使用Qt Gui进行实时视频源的Opencv人脸检测速度较慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60924711/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com