使用 OpenCV 和 Raspberry Pi 进行实时图像处理

Posted

技术标签:

【中文标题】使用 OpenCV 和 Raspberry Pi 进行实时图像处理【英文标题】:Live image processing with OpenCV and Raspberry Pi 【发布时间】:2017-02-01 22:34:49 【问题描述】:

最近,我正在努力加快在我的 Raspberry Pi 3 平台上运行的 OpenCV 中的图像处理速度。我做了人脸识别应用程序,但它工作得非常慢。我阅读了许多关于线程、多处理等的主题,但我仍然对此感到困惑。我用人脸检测来测试它只是为了让它更简单。这是我的代码:

pivideostream.py - 在线程中更新帧

from picamera.array import PiRGBArray
from picamera import PiCamera
from threading import Thread
import cv2

class PiVideoStream:

    def __init__(self, resolution=(640, 480), framerate=30):
        self.camera = PiCamera()
        self.camera.resolution = resolution
        self.camera.framerate = framerate
        self.rawCapture = PiRGBArray(self.camera, size=resolution)
        self.stream = self.camera.capture_continuous(self.rawCapture,format='bgr', use_video_port=True)
        self.image = None
        self.stopped = False

    def start(self):
        t = Thread(target=self.update)
        t.daemon = True
        t.start()
        return self

    def update(self):
        for frame in self.stream:
            self.image = frame.array
            self.rawCapture.truncate(0)

            if self.stopped:
                self.stream.close()
                self.rawCapture.close()
                self.camera.close()
                return  

    def read(self):
        return self.image

    def stop(self):
        self.stopped = True

process_img_thread.py - 主程序

from pivideostream import PiVideoStream
import cv2
from picamera.array import PiRGBArray
from picamera import PiCamera
import time


def detect_in_thread():
    # Start updating frames in threaded manner
    face_cascade = cv2.CascadeClassifier('./haarcascades/haarcascade_frontalface_default.xml')
    eye_cascade = cv2.CascadeClassifier('./haarcascades/haarcascade_eye.xml')
    thread_stream = PiVideoStream()
    thread_stream.start()
    time.sleep(2)

    # Read frames
    while True:

        # Original image
        image = thread_stream.read()

        # Full image - face detection
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray,1.3,5)
        for (x,y,w,h) in faces:
            detected_face = cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),2)

            # Region of interest - eyes detection 
            roi_color = image[y:y+h,x:x+w]
            roi_gray = gray[y:y+h,x:x+w]
            eyes = eye_cascade.detectMultiScale(roi_gray,1.03,5,0,(40,40))
            for (ex,ey,ew,eh) in eyes:
                cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,255),2)

        # Show computed image
        cv2.imshow('Threaded Camera OpenCV Preview',image)

        if cv2.waitKey(1) & 0xFF == ord("q"):
            break

    # Close image window and thread
    cv2.destroyAllWindows()
    thread_stream.stop()


if __name__ == "__main__":
    detect_in_thread()

当我从相机显示原始帧时效果很好,但是当我只在主程序中添加一些东西以处理图像时,视频速度约为 1 FPS :(。 有人可以帮我吗?

【问题讨论】:

人脸检测是一项昂贵的任务,而树莓派是一个缓慢的决策。也许可以试试 TK1 SoC,但不能保证足够快。 如果您知道图像中人脸的大致大小,您可以调整图像大小或限制检测大小。 【参考方案1】:

Micka 的建议非常好。

我在 Python 中线程化 OpenCV 时遇到了问题(不确定是否可行),但在线程化 PiCamera 帧抓取方面做得很好。

我除了上述尝试以下:

    使用“yuv”颜色空间而不是“rgb”,只需访问第一个(y - 亮度)通道即可获取灰度数据,从而减少获取帧和从 RGB 转换为灰度的时间 尝试使用 LBP 级联而不是 HAAR(例如 /usr/local/share/OpenCV/lbpcascades/lbpcascade_frontalface.xml) - 应该更快一些,但不太准确

【讨论】:

【参考方案2】:

jpeg等压缩格式捕获帧,它将加快捕获过程,

例如:

camera.capture_continuous(stream, format='jpeg', ....)

....

【讨论】:

以上是关于使用 OpenCV 和 Raspberry Pi 进行实时图像处理的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV Raspberry Pi printf()不显示

Opencv:无法打开显示:C++、Raspberry Pi 无头连接

在 Raspberry Pi 中使用 OpenCV 和套接字通过 TCP 发送视频

Raspberry Pi 上的 OpenCV 人脸检测速度很慢

Raspberry pi opencv 链接问题的交叉编译

树莓派最新官方系统安装Opencv(Raspberry Pi 11)