虚拟机下Ubuntu16.04+Qt5+OpenCV3 简单的笔记本前置摄像头UI界面上打开与关闭的实现

虚拟机下Ubuntu16.04+Qt5+OpenCV3 简单的笔记本前置摄像头UI界面上打开与关闭的实现


第一次写CSDN博客,还不太熟悉这个编辑器,哪里写得不妥的地方,希望得到大家的指正。
刚刚接触Qt和openCV,希望可以和大家一起学习。

测试摄像头

由于我在完成代码后运行了多次结果都没有画面,对代码的各种修改都没解决问题,然后才才想起来会不会是摄像头没有加载的问题。于是,我打开了cheese(这个ubuntu16.04应该是自带的),如果没有的话也不要紧,可以自行安装。

sudo apt-get install cheese 

我打开之后,发现果然是黑屏,虽然摄像头的灯是亮的,就是像这个样子,功能按键都是灰的。

虚拟机下Ubuntu16.04+Qt5+OpenCV3 简单的笔记本前置摄像头UI界面上打开与关闭的实现_第1张图片

然后我查了一下,发现大家的解决方案大致都是先检查摄像头是否加载成功,再切换USB兼容性

lsusb       //查看一下是否有找到摄像头
ls /dev | grep video    //查看是否有video0,即默认的前置摄像头

但我发现我的摄像头是加载了的
虚拟机下Ubuntu16.04+Qt5+OpenCV3 简单的笔记本前置摄像头UI界面上打开与关闭的实现_第2张图片

再切换了usb接口的兼容性(虚拟机->设置->USB控制器->USB兼容性,大概就是3.0和2.0切换吧),也还是没有解决问题。
那就很迷了,为什么就是显示不出来呢。

然后参考这篇博文:https://blog.csdn.net/haoruojing/article/details/60963780

大概是这样解决的:
回到windows,此电脑右键–>管理->服务和应用程序–>服务,启动
虚拟机下Ubuntu16.04+Qt5+OpenCV3 简单的笔记本前置摄像头UI界面上打开与关闭的实现_第3张图片

启动VMware这几项,我是对VMware USB Arbitration service 重新启动了,然后设备管理器里的camera消失了,不过电脑重启即可。然后再打开虚拟机,打开ubuntu,连接摄像头,我还把USB兼容性改为了3.0,然后再打开cheese,就发现可以看到图像了。

实现代码

参考:https://www.cnblogs.com/annt/p/ant003.html

首先创建一个工程,我创建的是Qt Widgets Application,className是DUQU。

.pro文件

.pro文件里需要加入以下一些OpenCV的库

INCLUDEPATH += /usr/local/include \              #(这部分可能路径不太一样,可以打开文档查找一下)
/usr/local/include/opencv4

LIBS += /usr/local/lib/libopencv_highgui.so \
/usr/local/lib/libopencv_core.so \
/usr/local/lib/libopencv_imgproc.so \
/usr/local/lib/libopencv_imgcodecs.so \
/usr/local/lib/libopencv_videoio.so \
/usr/local/lib/libopencv_shape.so \
/usr/local/lib/libopencv_core.so.4.0

UI界面的实现

进入duqu.ui
放置两个Push Button:Open和Close
(可以把objectName分别改为openButton,closeButton,再把text也该一下)
一个Label:objectName为label
一个Scroll Area(作为放置Label的一个区域)
大致就是如下图所示
虚拟机下Ubuntu16.04+Qt5+OpenCV3 简单的笔记本前置摄像头UI界面上打开与关闭的实现_第4张图片

然后就是设置槽了,选中Push Button,右键选择 Go to slot,signal选择clicked(),两个Push Button都是这样操作。然后就会看到我们的ducu.cpp文件里相应地生成了两个暂时为空的槽函数:

void DUQU::on_openButton_clicked();
void DUQU::on_closeButton_clicked();

“duqu.h"

#ifndef DUQU_H
#define DUQU_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

namespace Ui {
class DUQU;
}

class DUQU : public QMainWindow
{
    Q_OBJECT

public:
    explicit DUQU(QWidget *parent = 0);    //构造函数
    ~DUQU();                               //析构函数

private slots:
    void nextFrame();                    //实现定时从摄像头取图并显示在label上的功能
    void on_openButton_clicked();        //打开摄像头
    void on_closeButton_clicked();       //关闭摄像头

private:
    Ui::DUQU *ui;
    cv::VideoCapture capture;            //一个获取视频的抽象接口结构
    cv::Mat frame;                       //一帧图像
    QImage image;                        //一张图像
    QTimer *timer;                       //定时器用于定时取帧,隔一段时间获取图像。
    QImage Mat2QImage(cv::Mat cvImg);    //Mat->QImage的转化
};

#endif // DUQU_H

“duqu.cpp”

#include "duqu.h"
#include "ui_duqu.h"

DUQU::DUQU(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::DUQU)
{
    ui->setupUi(this);
    ui->label->setScaledContents(true);// 图片自适应窗口控件大小
}

DUQU::~DUQU()
{
    delete ui;
    delete timer;
}

//Mat->QImage
QImage DUQU::Mat2QImage(cv::Mat cvImg)
{
    QImage qImg;
    cv::cvtColor(cvImg,cvImg,cv::COLOR_BGR2RGB);
    qImg=QImage((const unsigned char*)(cvImg.data),
                             cvImg.cols,cvImg.rows,          //宽,高
                             cvImg.step,                     //步长
                             QImage::Format_RGB888);         //24位图,RGB=[0,1,2]
    //return qImg.rgbSwapped();
    return qImg;
}


//打开摄像头
void DUQU::on_openButton_clicked()
{
    capture.open(0);          //打开默认的摄像头
    if (capture.isOpened())
    {
        capture >> frame;     //获取一帧图像
        if(frame.empty())
        {
            qDebug()<<"error!";
        }
        if(!frame.empty())
        {
            image = Mat2QImage(frame);      //Mat->QImage
            ui->label->setPixmap(QPixmap::fromImage(image));   //QImage->QPixmap,并将图像显示在label上
            timer = new QTimer(this);  //计时器
            timer->setInterval(30);    //设置间隔:30毫秒
            connect(timer,SIGNAL(timeout()),this,SLOT(nextFrame()));
                                           //一旦超时则触发nextFrame(),即显示下一帧图像
                                           //SIGNAL(timeout()):每当计时结束,计时器归零并重新计时,并发送一个信号激活slot函数
            timer->start();       //重新开始计时
        }
    }
}

//显示下一帧图像
void DUQU::nextFrame()
{
    capture >> frame;          //获取的图像frame是Mat数据矩阵
    image = Mat2QImage(frame);//Mat->QImage
    ui->label->setPixmap(QPixmap::fromImage(image));    //fromImage(image): QImage->QPixmap
                                                        //最后将 QPixmap 将图像显示在label上
}

//关闭摄像头
void DUQU::on_closeButton_clicked()
{
    timer->stop();                    //停止计时
    capture.release();                //关闭摄像头
    ui->label->setPixmap(QPixmap());  //释放内存,关闭画面
}

“main.cpp”

#include "duqu.h"
#include 

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    DUQU *w=new DUQU;
    w->show();

    return app.exec();
}

实现效果

虚拟机下Ubuntu16.04+Qt5+OpenCV3 简单的笔记本前置摄像头UI界面上打开与关闭的实现_第5张图片

这样就完成一个简单的ui界面上的摄像头的打开与关闭了。

你可能感兴趣的:(Qt_OpenCV)