【正点原子Linux连载】第十八章 Camera 摘自【正点原子】I.MX6U嵌入式Qt开发指南V1.0.2

1)实验平台:正点原子阿尔法Linux开发板
2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-300792-1-1.html
4)对正点原子Linux感兴趣的同学可以加群讨论:935446741

第十八章 Camera

此章节例程适用于Ubuntu和正点原子I.MX6U开发板,不适用于Windows(需要自行修改才能适用Windows,Windows上的应用不在我们讨论范围)!

19.1 资源简介

正点原子I.MX6U开发板底板上有一路“CSI”摄像头接口。支持正点原子的OV5640、OV2640和OV7725(不带FIFO)。同时有USB接口,可以接USB免驱摄像头。例程兼容USB摄像头与正点原子的OV5640、OV2640和OV7725摄像头。
出厂系统请更新到正点原子I.MX6U最新的出厂系统,在驱动层正点原子对OV5640、OV2640和OV7725摄像头维护、优化或者添加支持。

19.2 环境搭建

Qt里也有一个QCamera类。没错,确实可以使用这个QCamera类来开发摄像头。但是这个类在正点原子的I.MX6U开发板4.1.15内核版本上不能使用OV5640、OV2640和OV7725,可以使用USB免驱摄像头。因为OV5640、OV2640和OV7725的驱动默认是读取YUYV格式数据,而QCamera里读取的数据是RGB格式数据,它们可能数据对不上就无法使用了!但是也不建议修改驱动的方法来使用QCamera,防止QCamera在某些方法上与驱动层不对应,导致使用报错。
实际上我们使用V4l2编程就可以对摄像头进行编程,效果会比在Qt显示流畅,因为V4l2的数据直接可以显示在fb0(也就是屏上)。而经过Qt还需要在控件上处理,所以效率会慢一些!在正点原子I.MX6U开发板上或者说是嵌入式上,比较低性能的CPU对于处理图像等大数据还是比较吃力的。所以我们需要去优化,不同的编程方式,对数据的处理不同,写出来的效果也会不同!
下面主要介绍Qt + OpenCV调用摄像头,效果肯定不能与使用V4l2直接显示在fb0上相比。在这个开发板的CPU上显示效果还是比较好的,还能接受,流畅度一般。
要想在Ubuntu上使用OpenCV,那么我们的Ubuntu上必须有OpenCV的库,如果您不想在Ubuntu安装OpenCV,就可以跳过这小节,直接用出厂系统提供的交叉编译工具链,里面已经提供有OpenCV。在Ubuntu上安装OpenCV只是方便我们测试界面,编写的程序也可以在Ubuntu上运行。安装的步骤也比较简单。
正点原子I.MX6U出厂系统的OpenCV版本为3.1.0。也不一定非要与正点原子I.MX6U出厂系统里的OpenCV相同版本,我们只是在Ubuntu上运行OpenCV。其中用到的API在3.1.0版本与3.4.1版本基本没有什么区别。3.1.0版本的OpenCV与3.4.1版本的OpenCV绝大多数核心API都相同,不必要担心找不到相同的API。
这里编者选择安装到OpenCV版本为3.4.1版本,因为3.1.0版本在配置cmake时下载的第三方库因为网络的原因难下载,导致cmake配置不过去。(PS:如果不是因为编译不过去,编者会选择与开发板相同的版本的OpenCV的)。
进入OpenCV的官网https://opencv.org/releases。下载3.4.1版本的OpenCV,如下图。我们选择Sources(源码)进行下载。
【正点原子Linux连载】第十八章 Camera 摘自【正点原子】I.MX6U嵌入式Qt开发指南V1.0.2_第1张图片

右键选择复制下载链接,用迅雷下载会比较快。下载完成后我们拷贝下载的文件到Ubuntu上进行解压。或者直接在正点原子的I.MX6U的光盘资料路径下找到开发板光盘A-基础资料/1、例程源码/7、第三方库源码/opencv-3.4.1.tar.gz。然后拷贝到Ubuntu下。
如下图我们已经下载好文件,并拷贝下载好的文件到Ubuntu的家目录下。
在这里插入图片描述

执行下面的指令进行解压。解压将会得到一个opencv-3.4.1文件夹,我们使用cd指令进入此文件夹。

tar xf opencv-3.4.1.tar.gz
cd opencv-3.4.1
安装cmake,用于生成编译OpenCV所需要的文件。
sudo apt-get install cmake  
新建一个build目录,并进入,用于编译生成的文件。
mkdir build
cd build

在这里插入图片描述

执行cmake配置编译。注意下面的指令“…”不要漏了!这里表示上一层目录。cmake会从上一层目录下找配置项,并配置到当前目录。

cmake ..
在配置的过程中cmake会下载一些库,如 ippicv_2017u3_lnx_intel64_general_20170822.tgz,需要一段时间,请等待,如果不能下载成功请重复尝试。
cmake配置成功如下图。

【正点原子Linux连载】第十八章 Camera 摘自【正点原子】I.MX6U嵌入式Qt开发指南V1.0.2_第2张图片

执行make开始编译。输入下面的指令。

make -j 16					// 以实际分配给虚拟机的核心数为准,最佳为分配给虚拟机核心数据的2倍。编者的虚拟机最大分配了16个核心,编者个人的电脑并不快,就是核心多,所以编译就快。编译完成耗时约5分钟。不要只输入make,否则将编译很久!需要加参数 -j n,n请根据个人虚拟机的实际情况。

【正点原子Linux连载】第十八章 Camera 摘自【正点原子】I.MX6U嵌入式Qt开发指南V1.0.2_第3张图片
【正点原子Linux连载】第十八章 Camera 摘自【正点原子】I.MX6U嵌入式Qt开发指南V1.0.2_第4张图片

执行下面的指令安装,安装到系统目录,需要加sudo权限。
sudo make install

【正点原子Linux连载】第十八章 Camera 摘自【正点原子】I.MX6U嵌入式Qt开发指南V1.0.2_第5张图片

安装完成如下。可以看到库被安装到/usr/local/lib下,头文件被安装在/usr/local/include下。

【正点原子Linux连载】第十八章 Camera 摘自【正点原子】I.MX6U嵌入式Qt开发指南V1.0.2_第6张图片

我们只需要知道安装的库路径和头文件路径即可在Qt里调用Ubuntu安装的OpenCV。头文件作用来编写程序,库路径用来运行程序时调用。我们只要在Qt的pro项目文件里指定这两个路径即可。

19.3 应用实例

请根据【正点原子】I.MX6U 出厂系统Qt交叉编译环境搭建V1.x.pdf(x >= 6)的文档搭建好I.MX6U的交叉编译环境。交叉编译工具链里已经有OpenCV,所以我们只要在我们搭建的交叉环境下就可以调用OpenCV的相关API进行编写Qt项目了。
项目简介:Qt加OpenCV打开摄像头采集图像并拍照。
例05_opencv_camera,Qt Camera编程(难度:较难)。项目路径为Qt/3/05_opencv_camera。
用脚本打开Qt Creator,必须按出厂系统Qt交叉编译环境搭建V1.x.pdf(x >= 6)的文档搭建好交叉编译环境,用脚本启动时,脚本有相应的环境变量,编译时会用到。

/opt/Qt5.12.9/Tools/QtCreator/bin/qtcreator.sh &	
编写程序应使用我们搭建的ATK-I.MX6U套件编写,否则若选择了Desktop Qt 5.12.9 GCC 64bit,如果我们的Ubuntu没有安装OpenCV就会使用不了OpenCV。如果您在19.2小节已经安装过OpenCV,那么下面两个套件都可一起选。本次编者两个一起选,因为编者有USB摄像头可以在Ubutnu上使用OpenCV测试,编写的程序交叉编译后在I.MX6U开发板使用USB免驱摄像头或者正点原子OV5640/OV7725(不带FIFO款)/OV2640测试成功!

【正点原子Linux连载】第十八章 Camera 摘自【正点原子】I.MX6U嵌入式Qt开发指南V1.0.2_第7张图片

下面开始编写程序。首先我们需要在项目pro文件添加OpenCV库的支持及头文件路径。

05_opencv_camera.pro文件如下,添加以下内容,这里主要是判断交叉编译器的类型,然后链接到不同的头文件路径与库。

1   QT       += core gui
2 
3   greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
4 
5   CONFIG += c++11
6 
7   # The following define makes your compiler emit warnings if you use
8   # any Qt feature that has been marked deprecated (the exact warnings
9   # depend on your compiler). Please consult the documentation of the
10  # deprecated API in order to know how to port your code away from it.
11  DEFINES += QT_DEPRECATED_WARNINGS
12
13  # You can also make your code fail to compile if it uses deprecated APIs.
14  # In order to do so, uncomment the following line.
15  # You can also select to disable deprecated APIs only up to a certain version of Qt.
16  #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
17
18  TARGET_ARCH = $${QT_ARCH}
19  contains(TARGET_ARCH, arm){
20      CONFIG += link_pkgconfig
21      PKGCONFIG += opencv
22      INCLUDEPATH += /opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi/usr/include
23  } else {
24      LIBS += -L/usr/local/lib \
25              -lopencv_core \
26              -lopencv_highgui \
27              -lopencv_imgproc \
28              -lopencv_videoio \
29              -lopencv_imgcodecs
30
31      #INCLUDEPATH可写可不写,系统会到找到此路径
32      INCLUDEPATH += /usr/local/include
33  }
34
35  SOURCES += \
36      camera.cpp \
37      main.cpp \
38      mainwindow.cpp
39
40  HEADERS += \
41      camera.h \
42      mainwindow.h
43
44  # Default rules for deployment.
45  qnx: target.path = /tmp/$${TARGET}/bin
46  else: unix:!android: target.path = /opt/$${TARGET}/bin
47  !isEmpty(target.path): INSTALLS += target

第18行,获取编译器的类型。
第19行,判断交叉编译器的类型是否为arm。
第22行,arm对应opencv的头文件路径,可以不写,编译不会报错,但是我们想查看对应的头文件,就不得不包括这个路径了,否则跳转不过去!
第24~32行,添加库的支持。-L后面指的是库文件路径,-l后面的是相关库参数(l是大字母“L”的小写字母“l”,不是一),如果不会写库的名称,可以参考Ubuntu的OpenCV安装路径下的/usr/local/lib/pkgconfig/opencv.pc文件。
camera.h文件,此文件声明了一个Camera类,其内容如下,比较简单。

9   #ifndef CAMERA_H
10  #define CAMERA_H
11
12  #include <QImage>
13  #include <QTimer>
14  /* 使用命名空间cv下的VideoCapture与Mat类 */
15  namespace cv {
16  class VideoCapture;
17  class Mat;
18  }
19
20  class Camera : public QObject
21  {
22      Q_OBJECT
23  public:
24      explicit Camera(QObject *parent = nullptr);
25      ~Camera();
26
27  signals:
28      /* 声明信号,用于传递有图片信号时显示图像 */
29      void readyImage(const QImage&);
30
31  public slots:
32      /* 用于开启定时器 */
33      bool cameraProcess(bool);
34
35      /* 选择摄像头 */
36      void selectCameraDevice(int);
37
38  private slots:
39      /* 定时器时间到处理函数,发送图像数据信号 */
40      void timerTimeOut();
41
42  private:
43      /* 声明OpenCV的cv命名空间下的VideoCapture对象 */
44      cv::VideoCapture * capture;
45
46      /* 定时器 */
47      QTimer * timer;
48
49      /* 图像转换处理函数 */
50      QImage matToQImage(const cv::Mat&);
51  };
52
53  #endif // CAMERA_H
54

camera.cpp类的定义如下。

9   #include "camera.h"
10  #include "opencv2/core/core.hpp"
11  #include "opencv2/highgui/highgui.hpp"
12  #include <QImage>
13  #include <QDebug>
14
15  Camera::Camera(QObject *parent) :
16      QObject(parent)
17  {
18      /* 实例化 */
19      capture = new cv::VideoCapture();
20      timer = new QTimer(this);
21
22      /* 信号槽连接 */
23      connect(timer, SIGNAL(timeout()), this, SLOT(timerTimeOut()));
24  }
25
26  Camera::~Camera()
27  {
28      delete capture;
29      capture = NULL;
30  }
31
32  void Camera::selectCameraDevice(int index)
33  {
34      /* 如果有其他摄像头打开了,先释放 */
35      if (capture->isOpened()) {
36          capture->release();
37      }
38
39      /* 打开摄像头设备 */
40      capture->open(index);
41  }
42
43  bool Camera::cameraProcess(bool bl)
44  {
45      if (bl) {
46          /* 为什么是33?1000/33约等于30帧,也就是一秒最多显示30帧  */
47          timer->start(33);
48      } else {
49          timer->stop();
50      }
51      /* 返回摄像头的状态 */
52      return capture->isOpened();
53  }
54
55  void Camera::timerTimeOut()
56  {
57      /* 如果摄像头没有打开,停止定时器,返回 */
58      if (!capture->isOpened()) {
59          timer->stop();
60          return;
61      }
62
63      static cv::Mat frame;
64      *capture >> frame;
65      if (frame.cols)
66          /* 发送图片信号 */
67          emit readyImage(matToQImage(frame));
68  }
69
70  QImage Camera::matToQImage(const cv::Mat &img)
71  {
72      /* USB摄像头和OV5640等都是RGB三通道,不考虑单/四通道摄像头 */
73      if(img.type() == CV_8UC3) {
74          /* 得到图像的的首地址 */
75          const uchar *pimg = (const uchar*)img.data;
76
77          /* 以img构造图片 */
78          QImage qImage(pimg, img.cols, img.rows, img.step,
79                        QImage::Format_RGB888);
80
81          /* 在不改变实际图像数据的条件下,交换红蓝通道 */
82          return qImage.rgbSwapped();
83      }
84
85      /* 返回QImage */
86      return QImage();
87  }
mainwindow.h头文件代码如下。
    /******************************************************************
    Copyright © Deng Zhimao Co., Ltd. 1990-2021. All rights reserved.
    * @projectName   05_opencv_camera
    * @brief         mainwindow.h
    * @author        Deng Zhimao
    * @email         [email protected]
    * @net            www.openedv.com
    * @date           2021-03-17
    *******************************************************************/
1   #ifndef MAINWINDOW_H
2   #define MAINWINDOW_H
3 
4   #include <QMainWindow>
5   #include <QVBoxLayout>
6   #include <QHBoxLayout>
7   #include <QComboBox>
8   #include <QPushButton>
9   #include <QVBoxLayout>
10  #include <QLabel>
11  #include <QScrollArea>
12  #include <QDebug>
13
14  class Camera;
15
16  class MainWindow : public QMainWindow
17  {
18      Q_OBJECT
19
20  public:
21      MainWindow(QWidget *parent = nullptr);
22      ~MainWindow();
23
24  private:
25      /* 主容器,Widget也可以当作一种容器 */
26      QWidget *mainWidget;
27
28      /* 滚动区域,方便开发高分辨率 */
29      QScrollArea *scrollArea;
30
31      /* 将采集到的图像使用Widget显示 */
32      QLabel *displayLabel;
33
34      /* 界面右侧区域布局 */
35      QHBoxLayout *hboxLayout;
36
37      /* 界面右侧区域布局 */
38      QVBoxLayout *vboxLayout;
39
40      /* 界面右侧区域容器 */
41      QWidget *rightWidget;
42
43      /* 界面右侧区域显示拍照的图片 */
44      QLabel *photoLabel;
45
46      /* 界面右侧区域摄像头设备下拉选择框 */
47      QComboBox *comboBox;
48
49      /* 两个按钮,一个为拍照按钮,另一个是开启摄像头按钮 */
50      QPushButton *pushButton[2];
51
52      /* 拍照保存的照片 */
53      QImage saveImage;
54
55      /* 摄像头设备 */
56      Camera *camera;
57
58      /* 布局初始化 */
59      void layoutInit();
60
61      /* 扫描是否存在摄像头 */
62      void scanCameraDevice();
63
64  private slots:
65      /* 显示图像 */
66      void showImage(const QImage&);
67
68      /* 设置按钮文本 */
69      void setButtonText(bool);
70
71      /* 保存照片到本地 */
72      void saveImageToLocal();
73  };
74  #endif // MAINWINDOW_H
mainwindow.cpp源文件代码如下。
    /******************************************************************
    Copyright © Deng Zhimao Co., Ltd. 1990-2021. All rights reserved.
    * @projectName   05_opencv_camera
    * @brief         mainwindow.cpp
    * @author        Deng Zhimao
    * @email         [email protected]
    * @net            www.openedv.com
    * @date           2021-03-17
    *******************************************************************/
1   #include "mainwindow.h"
2   #include <QGuiApplication>
3   #include <QScreen>
4   #include <QFile>
5   #include <QPixmap>
6   #include <QBuffer>
7   #include "camera.h"
8  
9   MainWindow::MainWindow(QWidget *parent)
10      : QMainWindow(parent)
11  {
12      /* 布局初始化 */
13      layoutInit();
14 
15      /* 扫描摄像头 */
16      scanCameraDevice();
17  }
18 
19  MainWindow::~MainWindow()
20  {
21  }
22 
23  void MainWindow::layoutInit()
24  {
25      /* 获取屏幕的分辨率,Qt官方建议使用这
26       * 种方法获取屏幕分辨率,防上多屏设备导致对应不上
27       * 注意,这是获取整个桌面系统的分辨率
28       */
29      QList <QScreen *> list_screen =  QGuiApplication::screens();
30 
31      /* 如果是ARM平台,直接设置大小为屏幕的大小 */
32  #if __arm__
33      /* 重设大小 */
34      this->resize(list_screen.at(0)->geometry().width(),
35                   list_screen.at(0)->geometry().height());
36  #else
37      /* 否则则设置主窗体大小为800x480 */
38      this->resize(800, 480);
39  #endif
40 
41      /* 实例化与布局,常规操作 */
42      mainWidget = new QWidget();
43      photoLabel = new QLabel();
44      rightWidget = new QWidget();
45      comboBox = new QComboBox();
46      pushButton[0] = new QPushButton();
47      pushButton[1] = new QPushButton();
48      scrollArea = new QScrollArea();
49      displayLabel = new QLabel(scrollArea);
50      vboxLayout = new QVBoxLayout();
51      hboxLayout = new QHBoxLayout();
52 
53      vboxLayout->addWidget(photoLabel);
54      vboxLayout->addWidget(comboBox);
55      vboxLayout->addWidget(pushButton[0]);
56      vboxLayout->addWidget(pushButton[1]);
57 
58      rightWidget->setLayout(vboxLayout);
59 
60      hboxLayout->addWidget(scrollArea);
61      hboxLayout->addWidget(rightWidget);
62      mainWidget->setLayout(hboxLayout);
63 
64      this->setCentralWidget(mainWidget);
65 
66      pushButton[0]->setMaximumHeight(40);
67      pushButton[0]->setMaximumWidth(200);
68 
69      pushButton[1]->setMaximumHeight(40);
70      pushButton[1]->setMaximumWidth(200);
71 
72      comboBox->setMaximumHeight(40);
73      comboBox->setMaximumWidth(200);
74      photoLabel->setMaximumSize(100, 75);
75      scrollArea->setMinimumWidth(this->width()
76                                  - comboBox->width());
77 
78      /* 显示图像最大画面为xx */
79      displayLabel->setMinimumWidth(scrollArea->width() * 0.75);
80      displayLabel->setMinimumHeight(scrollArea->height() * 0.75);
81      scrollArea->setWidget(displayLabel);
82 
83      /* 居中显示 */
84      scrollArea->setAlignment(Qt::AlignCenter);
85 
86      /* 自动拉伸 */
87      photoLabel->setScaledContents(true);
88      displayLabel->setScaledContents(true);
89 
90      /* 设置一些属性 */
91      pushButton[0]->setText("拍照");
92      pushButton[0]->setEnabled(false);
93      pushButton[1]->setText("开始");
94      pushButton[1]->setCheckable(true);
95 
96      /* 摄像头 */
97      camera = new Camera(this);
98 
99      /* 信号连接槽 */
100     connect(camera, SIGNAL(readyImage(QImage)),
101             this, SLOT(showImage(QImage)));
102     connect(pushButton[1], SIGNAL(clicked(bool)),
103             camera, SLOT(cameraProcess(bool)));
104     connect(pushButton[1], SIGNAL(clicked(bool)),
105             this, SLOT(setButtonText(bool)));
106     connect(pushButton[0], SIGNAL(clicked()),
107             this, SLOT(saveImageToLocal()));
108
109 }
110
111 void MainWindow::scanCameraDevice()
112 {
113     /* 如果是Windows系统,一般是摄像头0 */
114 #if win32
115     comboBox->addItem("windows摄像头0");
116     connect(comboBox,
117             SIGNAL(currentIndexChanged(int)),
118             camera, SLOT(selectCameraDevice(int)));
119 #else
120     /* QFile文件指向/dev/video0 */
121     QFile file("/dev/video0");
122
123     /* 如果文件存在 */
124     if (file.exists())
125         comboBox->addItem("video0");
126     else {
127         displayLabel->setText("无摄像头设备");
128         return;
129     }
130
131     file.setFileName("/dev/video1");
132
133     if (file.exists()) {
134         comboBox->addItem("video1");
135         /* 开发板ov5640等设备是1 */
136         comboBox->setCurrentIndex(1);
137     }
138
139     file.setFileName("/dev/video2");
140
141     if (file.exists())
142         /* 开发板USB摄像头设备是2 */
143         comboBox->addItem("video2");
144
145 #if !__arm__
146     /* ubuntu的USB摄像头一般是0 */
147     comboBox->setCurrentIndex(0);
148 #endif
149
150     connect(comboBox,
151             SIGNAL(currentIndexChanged(int)),
152             camera, SLOT(selectCameraDevice(int)));
153 #endif
154 }
155
156 void MainWindow::showImage(const QImage &image)
157 {
158     /* 显示图像 */
159     displayLabel->setPixmap(QPixmap::fromImage(image));
160     saveImage = image;
161
162     /* 判断图像是否为空,空则设置拍照按钮不可用 */
163     if (!saveImage.isNull())
164         pushButton[0]->setEnabled(true);
165     else
166         pushButton[0]->setEnabled(false);
167 }
168
169 void MainWindow::setButtonText(bool bl)
170 {
171     if (bl) {
172         /* 设置摄像头设备 */
173         camera->selectCameraDevice(comboBox->currentIndex());
174         pushButton[1]->setText("关闭");
175     } else {
176         /* 若关闭了摄像头则禁用拍照按钮 */
177         pushButton[0]->setEnabled(false);
178         pushButton[1]->setText("开始");
179     }
180 }
181
182 void MainWindow::saveImageToLocal()
183 {
184     /* 判断图像是否为空 */
185     if (!saveImage.isNull()) {
186         QString fileName =
187                 QCoreApplication::applicationDirPath() + "/test.png";
188         qDebug()<<"正在保存"<<fileName<<"图片,请稍候..."<<endl;
189
190         /* save(arg1,arg2,arg3)重载函数,arg1代表路径文件名,
191          * arg2保存的类型,arg3代表保存的质量等级 */
192         saveImage.save(fileName, "PNG", 1);
193
194         /* 设置拍照的图像为显示在photoLabel上 */
195         photoLabel->setPixmap(QPixmap::fromImage(QImage(fileName)));
196
197         qDebug()<<"保存完成!"<<endl;
198     }
199 }
200
第111~154行,判断linux下的设备/dev/video*。细心的同学发现,这个程序是Linux下用的。当然Windows也是可以使用OpenCV的,需要自己修改pro文件链接到Windows的OpenCV库-L需要修改为-LD,Windows下的库文件是dll类型,此外不考虑macOS系统,具体情况编者没得实验。

19.4 程序运行效果

【正点原子Linux连载】第十八章 Camera 摘自【正点原子】I.MX6U嵌入式Qt开发指南V1.0.2_第8张图片

选择合适的摄像头设备,(注意如果在Ubuntu使用USB摄像头,需要设置USB的兼容性为3.0反之2.0,具体需要看不同摄像头设备,点击连接摄像头到虚拟机。可以先使用Ubuntu18.04自带的茄子拍照软件,检测摄像头是否可用)。点击拍照,可以看程序输出的Debug信息,保存照片的路径为当前可执行程序的路径,保存照片名称为test.png,右上角显示保存照片的缩略图,再次点击拍照则会替换已经保存过的照片。若想要保存多个照片可自行设计。
若在正点原子I.MX6U开发板上运行此程序,先插上摄像头,确保摄像头能用,注意不要选择video0,video0是NXP的pxp驱动产生的节点,不是摄像头,否则会报错。I.MX6U开发板是单核A7的CPU,性能有限,所以流畅度一般,还可以。但是在保存照片时会比PC电脑慢好多,不过也不能太勉强这个6ULL芯片了啦,能拍照已经不错了,或者大家可以对保存照片步骤进行优化,开启一个线程进行优化,剩下的交给大家了,大家可以的。
OpenCV在不设置摄像头分辨率时会采用默认分辨率640*480 30fps(绝大多数摄像头都是支持这个分辨率)。USB免驱摄像头可以使用下面的方法来设置分辨率。

capture->open(1);
capture ->set(CV_CAP_PROP_FRAME_WIDTH, 320);
capture ->set(CV_CAP_PROP_FRAME_HEIGHT, 240);
但是正点原子6ULL开发板上的OV5640/OV2640/OV7725(不带FIFO款)摄像头就不可以直接使用些方法设置采集分辨率了,因为驱动里设置分辨率的方法与标准的V4L2设置分辨有些差异。也可以直接使用正点原子I.MX6U里的摄像头采集分辨率设置软件camera_settings直接设置,注意在处理图像中的matToQImage函数需要以确认的分辨率进行转换使用了。
总结,想要在Qt中使用OpenCV,那么我们的开发板文件系统里或者Ubuntu系统必须要有OpenCV的库。对于某些非通用的USB摄像头来说,因为驱动层限制不能直接使用Qt自带的QCamera类。

你可能感兴趣的:(LINUX,qt,linux,开发语言)