zoukankan      html  css  js  c++  java
  • Qt:在QCamera上绘图(QCamera as background)

    举个例子:

    背景:
    几年前在某家人脸识别公司工作时,做了几个演示用的demo(FaceView),其中大量用到了绘图方面的Qt方法。
    核心就是:在摄像头的视频流上绘制人脸框、性别、年龄等等。好在当时是使用openCV来捕获摄像头,后面在绘图事件中刷新,所以实际写起来起来非常简单。

    这次在MMI中也遇到了这个问题,开发时考虑到对相机的要求不高,能看就行,于是采用了QCamera->QCameraViewfinder一系列操作。
    就在快要验收的时候,甲方爸爸提出:不要使用一大块取景器,最好像手机识别那样的圆框。

    尝试解决:
    网上的一些方法,继承QCameraViewfinder之后重写paintEvent()。实际debug时,发现paintEvent只有窗体被show出来的时候调用了一次,没有update,更别说画图了。

    解决:
    后来在某个issue下看到有人提到QAbstractVideoSurface,于是去大概了解了一下。
    QCamera初始化完成后,可以用setViewfinder()方法来设置数据流往哪走。
    void setViewfinder(QVideoWidget *viewfinder);
    void setViewfinder(QGraphicsVideoItem *viewfinder);
    void setViewfinder(QAbstractVideoSurface *surface);

    这里提到的就是第三种方法,追到QAbstractVideoSurface类中,结合Qt手册可以看到:
    virtual bool present(const QVideoFrame &frame) = 0;
    [pure virtual] bool QAbstractVideoSurface::present(const QVideoFrame &frame)
    Presents a video frame.Returns true if the frame was presented, and false if an error occurred.
    说白了就是把帧丢出来,给我们自己处理。

    这样一来,整条线就打通了,从取数据->绘画->渲染。

    实现:
    要实现上述功能,首先需要对数据进行处理。
    1.新建类VideoSurface,继承自QAbstractVideoSurface,可以把它理解成数据源。继承后,supportedPixelFormats(...)、present(...)这两个纯虚函数实现一下,同时别忘记加上信号,以方便把我们的数据扔出去给其他控件使用;
    2.新建类ViewFinder,继承自QLabel,可以把它理解成取景器的QWidget。选择用QLabel是因为比较容易把图片放上来(setPixmap),重写它的paintEvent()。注意:重写的绘图事件中,一定要先调用QLabel::paintEvent(event),否则外面触发的update都不会被渲染;
    3.在原本的相机类中,用VideoSurface取代QCameraViewfinder(注意:这时候VideoSurface不是QWidget了,要将ViewFinder当做Widget,设定父窗口、父窗口等)。在这里定义一个槽,用来接收步骤1中的信号,获取图片;
    4.使用setPixmap方法,给ViewFinder加上相机的背景。调用此方法时,会进入ViewFinder的绘图事件,在步骤2所说的QLabel::paintEvent(event)后,添加画图的工序。

    上述步骤完成后,即可大功告成。

    我绘制的是一张png图片,把这张图片换成切好的人脸识别框,就可以实现甲方爸爸的需求了。当然,也可以自己用蒙版画出来一个圆。
    具体的实现代码,见https://github.com/zhujingran/PaintOnQCamera

  • 相关阅读:
    TCP的初始cwnd和ssthresh
    C/C++ main
    PHP Function
    run bin
    PHP
    LAMP
    PHP MATH
    PHP array sort
    inline
    gcc g++
  • 原文地址:https://www.cnblogs.com/zhunix/p/14752270.html
Copyright © 2011-2022 走看看