(四)加入摄像头的系统

打开摄像头的方法在第一章里就讲到了,而且使用了多线程完成。所以这一章的内容就是将之前第一章的代码做移植,进行小幅度的修改,应用到当前系统上就可以了。


在UI界面上已经放好了用来显示摄像头信息的label

在项目中创建一个新的线程,用于处理摄像头有关的数据

class CamerWidget_camer_thread : public QThread
{
    Q_OBJECT
public:
    explicit CamerWidget_camer_thread(QObject *parent = 0);
    ~CamerWidget_camer_thread();

    void stop();

    QImage Mat2QImage(cv::Mat cvImg);
    void opencam();
    cv::Mat frame;
    cv::VideoCapture capture;
    struct CamerInfo_data camer_info_data;

public slots:

protected:
    void run();

signals:
    void camer_image_sig(struct CamerInfo_data);

private:
    volatile bool stopped;

};

具体的函数实现可以参考第一章的代码

自定义了一个新的结构体用于存放摄像头有关的数据

// opencv camer info struct
struct CamerInfo_data
{
    QImage image;
    double fps;
};

在线程中发射信号

emit camer_image_sig(camer_info_data); //emit image signal

在主线程中接收信号并更新显示

void CamerWidget::camer_updata(CamerInfo_data camer_info_data)
{
    ui->camer_label->setPixmap(QPixmap::fromImage(camer_info_data.image).scaled(ui->camer_label->size()));

    //this->update();
}

为了提高兼容性,在构造函数里对摄像头的设备结点进行了判断,如果存在设备节点才进行摄像头的处理,否则说明并没有识别到摄像头,显示错误信息。

QFile cam_dev("/dev/video0");
    if(cam_dev.open(QFile::ReadOnly))
    {
        cam_dev.close();
        camerwidget_camer_thread = new CamerWidget_camer_thread;
        //使用自定义结构体在信号槽中传递时需要先注册,否则会报错
        qRegisterMetaType<CamerInfo_data>("CamerInfo_data");

        connect(camerwidget_camer_thread,&CamerWidget_camer_thread::camer_image_sig,this,&CamerWidget::camer_updata);

        camerwidget_camer_thread->start();
    }
    else
    {
        ui->camer_label->setText("无摄像头设备信息");
        qDebug() << "No file named /dev/video0";
    }

使用QFile尝试打开设备节点,如果没有该设备结点或者打开失败,则会进入else中执行。

同样注意,因为在信号槽中使用了自定义的结构体,需要先注册

//使用自定义结构体在信号槽中传递时需要先注册,否则会报错
qRegisterMetaType<CamerInfo_data>("CamerInfo_data");

另外注意在析构函数中释放线程指针,否则容易导致内存泄漏。有关于指针的幅值,特别是在new的时候没有指定父对象的指针,一定要进行内存释放。

if(camerwidget_camer_thread->isRunning())
    {
        camerwidget_camer_thread->stop();
        camerwidget_camer_thread->wait();
        camerwidget_camer_thread->quit();
    }
delete camerwidget_camer_thread;

测试

 

补充

在PC端运行程序时,发现在关闭摄像头的时候会报错,但是再次打开也还是可以继续运行,但是在ARM板上运行时发现,这样做会导致程序崩溃,系统死机,报错信息如下。

GStreamer-CRITICAL **: gst_element_make_from_uri: assertion 'gst_uri_is_valid (uri)' failed
GStreamer: Error opening bin: no source element for URI "/dev/video0"

这是由于后端解码出现了问题,在QT下后端解码可以使用 vcl,mplayer,xine,gstreamer,在qt中使用gstreamer这个后端解码

apt-get install phonon-backend-gstreamer
apt-get install mplayer
apt-get install v4l-utils
v4l2-ctl -d /dev/video0 -D

 

Qt完整源码放在github上,有需要可以自行下载。 代码名称为190517.zip

https://github.com/ljy980330/opencv_face_sys

 

有任何问题可以在下面给我留言!大家一起学习!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
kingscada加入摄像头是指kingscada公司将摄像头作为其产品线的一部分。摄像头是一种用于捕捉影像的设备,可以将实时的视频图像传输给用户。kingscada加入摄像头主要是为了满足市场需求和客户需求,扩大产品范围,提供更全面的解决方案。 首先,摄像头加入可以使kingscada公司提供更多样化的产品选择。摄像头可用于安防监控、工业检测、视频会议等各个领域,可以满足不同行业和不同用户的需求。这样一来,kingscada可以提供更全面的解决方案,满足不同用户的需求,增加市场竞争力。 其次,摄像头作为物联网设备的一部分,可以与kingscada的其他产品相互配合使用。例如,摄像头可以与kingscada的监测仪表、控制系统等进行数据传输和交互,实现更智能的系统集成。这样一来,kingscada的整体解决方案将更加完善,提升用户体验。 另外,摄像头加入还可以拓宽kingscada的市场范围。随着人们对安全和数据监测的需求增加,摄像头市场的潜力不断扩大。kingscada加入摄像头后,可以进入到这个大市场中,获得更多的商机和市场份额。 总之,kingscada加入摄像头是为了满足市场需求和客户需求,提供更全面的解决方案,增加产品种类,拓宽市场范围。通过加入摄像头,kingscada可以进一步提升自身的竞争力,为用户提供更多样化、更智能化的解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值