完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1、效果图
2、补丁(参考 commit a3aab64424a416879be7651165e5b0b19da5400a Author: rockemd Date: Wed Dec 9 23:10:26 2020 +0800 support USB dual camera diff --git a/app/QUVCTest/QUVCTest.pro b/app/QUVCTest/QUVCTest.pro new file mode 100755 index 0000000..1b98345 --- /dev/null +++ b/app/QUVCTest/QUVCTest.pro @@ -0,0 +1,34 @@ + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 console + +TARGET = QUVCTest +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which as been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +#DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += + main.cpp + widget.cpp + v4l2.cpp + camerathread.cpp + +HEADERS += + widget.h + v4l2.h + camerathread.h + +FORMS += + widget.ui diff --git a/app/QUVCTest/camerathread.cpp b/app/QUVCTest/camerathread.cpp new file mode 100755 index 0000000..fc682bb --- /dev/null +++ b/app/QUVCTest/camerathread.cpp @@ -0,0 +1,35 @@ +#include "camerathread.h" +#include + +extern QLabel *mylabel; +extern QLabel *mylabel2; + +CameraThread::CameraThread() +{ + +} + +CameraThread::~CameraThread() +{ + +} + +/** 获取摄像头数据线程 */ +void CameraThread::dowork() +{ + av4l.V4l_Init("/dev/video44", 30); /** 初始化 */ + bv4l.V4l_Init("/dev/video43", 30); /** 初始化 */ + + while(1){ + if((QThread::currentThread()->isInterruptionRequested())){/** 是否有中断此线程信号 */ + av4l.Close_Camera(); /** 关闭摄像头 */ + bv4l.Close_Camera(); /** 关闭摄像头 */ + break; + } + currentimagea = av4l.Get_image(); /** 获得一帧图片数据 */ + currentimageb = bv4l.Get_image(); /** 获得一帧图片数据 */ + mylabel->setPixmap(QPixmap::fromImage(currentimagea)); /** 显示到label上 */ + mylabel2->setPixmap(QPixmap::fromImage(currentimageb)); /** 显示到label上 */ + } + +} diff --git a/app/QUVCTest/camerathread.h b/app/QUVCTest/camerathread.h new file mode 100755 index 0000000..48414e2 --- /dev/null +++ b/app/QUVCTest/camerathread.h @@ -0,0 +1,27 @@ +#ifndef CAMERATHREAD_H +#define CAMERATHREAD_H + +#include +#include "v4l2.h" +#include +#include "widget.h" +#include "ui_widget.h" + +class CameraThread : public QObject +{ + Q_OBJECT +public: + CameraThread(); + ~CameraThread(); + V4L2 av4l; + V4L2 bv4l; + QImage currentimagea; /** 保存摄像头一帧图片数据,然后显示到label上 */ + QImage currentimageb; /** 保存摄像头一帧图片数据,然后显示到label上 */ + +signals: + +public slots: + void dowork(); /** 获取摄像头数据线程 */ +}; + +#endif // CAMERATHREAD_H diff --git a/app/QUVCTest/main.cpp b/app/QUVCTest/main.cpp new file mode 100755 index 0000000..f92e588 --- /dev/null +++ b/app/QUVCTest/main.cpp @@ -0,0 +1,26 @@ +#include "widget.h" +#include +#include +#include "camerathread.h" + +QThread *ImageThread = new QThread; /** 获取摄像头数据线程 */ + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + Widget w; + + CameraThread *camera_worker = new CameraThread; + + camera_worker->moveToThread(ImageThread); /** 创建线程 */ + QObject::connect(ImageThread, SIGNAL(started()), + camera_worker, SLOT(dowork())); + QObject::connect(ImageThread, SIGNAL(finished()), + camera_worker, SLOT(deleteLater())); /** 当线程结束时,释放资源 */ + + ImageThread->start(); /** 启动线程 */ + + w.show(); + + return a.exec(); +} diff --git a/app/QUVCTest/v4l2.cpp b/app/QUVCTest/v4l2.cpp new file mode 100755 index 0000000..15e49f7 --- /dev/null +++ b/app/QUVCTest/v4l2.cpp @@ -0,0 +1,155 @@ +/** + * 功能:使用V4L2采集UVC摄像头数据 + * 日期:2018.3.26 + * 用法:在Ubuntu下的Qt工程中添加V4L2.h和V4L2.cpp文件,定义一个V4L2对象, + * 调用bool V4L2::V4l_Init(char* camera_path, unsigned int frame) 函数对摄像头进行初始化操作 + * 调用QImage V4L2::Get_image() 函数就可以获得摄像头传来的一张图片 + * 调用bool Close_Camera(void)函数关闭摄像头 + * 注意:需要在V4L2.cpp的54行左右可修改摄像头图片的输出格式,如修改为MJPEG输出 + * 在V4L2.h的宏定义中可以修改输出图片的像素 + * + * v1.1-2018.9.26:修改注释风格,规范代码 + * v1.2-2019.3.2:优化Get_image函数,减少数据转移次数 + */ + +#include "v4l2.h" + +V4L2::V4L2() +{ + n = 0; +} + +V4L2::~V4L2() +{ + +} + +/** 摄像头初始化,需要传入摄像头的挂载路径和输出的帧率,初始化成功则返回真 */ +bool V4L2::V4l_Init(char *camera_path, unsigned int frame) +{ + if((fd=open(camera_path, O_RDWR)) == -1){ /** 读写方式打开摄像头 */ + qDebug()<<"Error opening V4L interface"; + return false; + } + if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1){ /** 检查摄像头的信息 */ + qDebug()<<"Error opening device "< + }else{ /** 打印摄像头的信息 */ + qDebug()<<"driver:tt"< + + fmtdesc.index=0; + fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; /** 和struct v4l2_format中的type一致 */ + qDebug()<<"Support format:"; + while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1){ /** 获取摄像头输出图片所支持的格式 */ + qDebug()<<"tt"< + } + + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /** 像素格式 */ + fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; /** JPEG格式输出 */ + fmt.fmt.pix.height = Image_High; /** 图像尺寸,在这里设置想要输出的图片宽和高 */ + fmt.fmt.pix.width = Image_Width; + fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; /** 视频帧传输方式,交错式 */ + if(ioctl(fd, VIDIOC_S_FMT, &fmt) == -1){ /** 配置摄像头的采集格式 */ + qDebug()<<"Unable to set format"; + return false; + } + if(ioctl(fd, VIDIOC_G_FMT, &fmt) == -1){ /** 重新读取结构体,以确认完成设置 */ + qDebug()<<"Unable to get format"; + return false; + }else{ + qDebug()<<"fmt.type:tt"< + + setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + setfps.parm.capture.timeperframe.denominator = frame;/** 预期的帧率 */ + setfps.parm.capture.timeperframe.numerator = 1; /** fps=frame/1 */ + if(ioctl(fd, VIDIOC_S_PARM, &setfps)==-1){ /** 设置帧数 */ + qDebug()<<"Unable to set fps"; + return false; + } + if(ioctl(fd, VIDIOC_G_PARM, &setfps)==-1){ /** 重新读取结构体,以确认完成设置 */ + qDebug()<<"Unable to get fps"; + return false; + }else{ + qDebug()<<"fps:tt"< + + req.count=Video_count; /** 3个缓存区 */ + req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; /** 与struct v4l2_format中的type一致 */ + req.memory=V4L2_MEMORY_MMAP; /** Memory Mapping模式,设置为V4L2_MEMORY_MMAP时count字段才有效 */ + if(ioctl(fd,VIDIOC_REQBUFS,&req)==-1){ /** 向内核申请视频缓存 */ + qDebug()<<"request for buffers error"; + return false; + } + for (i=0; i + buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buffer.memory = V4L2_MEMORY_MMAP; + buffer.index = i; + if (ioctl (fd, VIDIOC_QUERYBUF, &buffer) == -1){ /** 获得缓冲区的参数,mmap时需要这些参数 */ + qDebug()<<"query buffer error"; + return false; + } + length = buffer.length; /** 保存缓存的大小 */ + start = (unsigned char *)mmap(NULL,buffer.length,PROT_READ |PROT_WRITE, MAP_SHARED, fd, buffer.m.offset); + /** 将申请的内核缓存映射到用户空间 */ + } + for (i=0; i + ioctl(fd, VIDIOC_QBUF, &buffer); /** 将缓存入队 */ + } + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + ioctl (fd, VIDIOC_STREAMON, &type); /** 开启I/O流 */ + + bzero(&v4lbuf, sizeof(v4lbuf)); + v4lbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + v4lbuf.memory = V4L2_MEMORY_MMAP; + qDebug()<<"init ok"; + + return true; +} + +QImage V4L2::Get_image() /** 得到摄像头捕获的图片,返回值为QImage类型的变量 */ +{ + v4lbuf.index = n%Video_count; + ioctl(fd, VIDIOC_DQBUF, &v4lbuf); /** 将获得图像数据的缓存出队 */ + + QByteArray temp; + temp.append((const char *)start[n%Video_count],length[n%Video_count]); + image.loadFromData(temp); /** 将图片数据放入image变量中 */ + + v4lbuf.index = n%Video_count; + ioctl(fd, VIDIOC_QBUF, &v4lbuf); /** 将已经读取过数据的缓存块重新入队 */ + n++; + if(n == 3){ /** 防止n累加溢出 */ + n = 0; + } + return image; /** 返回图片数据 */ +} + +bool V4L2::Close_Camera() /** 关闭摄像头,关闭成功则返回真 */ +{ + if(fd != -1){ + ioctl(fd, VIDIOC_STREAMOFF, &type); /** 结束图像显示 */ + int n = close(fd); /** 关闭视频设备 */ + if(n == -1){ + qDebug()<<"close camera failed"; + return false; + } + } + for(i=0; i + start = NULL; + } + } + return true; +} diff --git a/app/QUVCTest/v4l2.h b/app/QUVCTest/v4l2.h new file mode 100755 index 0000000..b417ea3 --- /dev/null +++ b/app/QUVCTest/v4l2.h @@ -0,0 +1,57 @@ +/** + * 功能:使用V4L2采集UVC摄像头数据 + * 日期:2018.3.26 + * 用法:在Ubuntu下的Qt工程中添加V4L2.h和V4L2.cpp文件,定义一个V4L2对象, + * 调用bool V4L2::V4l_Init(char* camera_path, unsigned int frame) 函数对摄像头进行初始化操作 + * 调用QImage V4L2::Get_image() 函数就可以获得摄像头传来的一张图片 + * 调用bool Close_Camera(void)函数关闭摄像头 + * 注意:需要在V4L2.cpp的54行左右可修改摄像头图片的输出格式,如修改为MJPEG输出 + * 在V4L2.h的宏定义中可以修改输出图片的像素 + * + * v1.1-2018.9.26:修改注释风格,规范代码 + * v1.2-2019.3.2:优化Get_image函数,减少数据转移次数 + */ + +#ifndef V4L2_H +#define V4L2_H + +#include +#include +#include +#include +#include +#include +#include + +#define Video_count 3 /** 缓冲帧数 */ +#define Image_Width 1280 /** 输出图片的像素 */ +#define Image_High 720 + +class V4L2 +{ +public: + V4L2(); + ~V4L2(); + bool V4l_Init(char *camera_path, unsigned int frame);/** 摄像头初始化函数,需要传入摄像头的挂载路径和输出的帧率,初始化成功则返回真 */ + QImage Get_image(void); /** 获取图片,返回值为QImage类型的变量 */ + bool Close_Camera(void); /** 关闭摄像头,关闭成功则返回真 */ + int n; /** 用在Get_image函数,获取图片时,用来控制哪快缓存 */ + +private: + int i; + int fd; /** 摄像头句柄 */ + int length[Video_count];/** 用来保存申请的缓存的大小 */ + QImage image; + unsigned char * start[Video_count];/** 用来保存图片数据 */ + + struct v4l2_buffer buffer[Video_count];/** 向内核申请缓存时用到此结构体,每一个struct v4l2_buffer对应内核摄像头驱动中的一个缓存 */ + struct v4l2_format fmt; /** 用来设置像素格式 图片输出格式 图像尺寸 扫描方式 */ + struct v4l2_fmtdesc fmtdesc; /** 获取摄像头输出图片所支持的格式时需要用到此结构体 */ + struct v4l2_capability cap; /** 检查摄像头的信息时需要用到此结构体 */ + struct v4l2_streamparm setfps; /** 设置帧率时用到此结构体 */ + struct v4l2_requestbuffers req; /** 向内核申请缓存时用到此结构体 */ + struct v4l2_buffer v4lbuf; /** 缓存出队 入队时用到此结构体 */ + enum v4l2_buf_type type; /** 开启I/O流时用到此结构体 */ +}; + +#endif // V4L2_H diff --git a/app/QUVCTest/widget.cpp b/app/QUVCTest/widget.cpp new file mode 100755 index 0000000..00bf7c3 --- /dev/null +++ b/app/QUVCTest/widget.cpp @@ -0,0 +1,30 @@ +#include "widget.h" +#include "ui_widget.h" + + +QLabel *mylabel = NULL; +QLabel *mylabel2 = NULL; +extern QThread *ImageThread; /** 获取摄像头数据线程 */ + +Widget::Widget(QWidget *parent) : + QWidget(parent), + ui(new Ui::Widget) +{ + ui->setupUi(this); + + mylabel = ui->label; /** 获得界面上的label对象, 使得可以在“获取摄像头数据线程”获取的图片数据显示到这个label上 */ + mylabel2 = ui->label2; /** 获得界面上的label对象, 使得可以在“获取摄像头数据线程”获取的图片数据显示到这个label上 */ +} + +Widget::~Widget() +{ + delete ui; +} + +/** 关闭窗口时候的处理函数 */ +void Widget::closeEvent(QCloseEvent *) +{ + ImageThread->requestInterruption(); /** 请求中断 */ + ImageThread->quit(); /** 关闭线程 */ + ImageThread->wait(); /** 同步关闭 */ +} diff --git a/app/QUVCTest/widget.h b/app/QUVCTest/widget.h new file mode 100755 index 0000000..9852ecc --- /dev/null +++ b/app/QUVCTest/widget.h @@ -0,0 +1,25 @@ +#ifndef WIDGET_H +#define WIDGET_H + +#include +#include + +namespace Ui { +class Widget; +} + +class Widget : public QWidget +{ + Q_OBJECT + +public: + explicit Widget(QWidget *parent = 0); + ~Widget(); + Ui::Widget *ui; + void closeEvent(QCloseEvent *); /** 关闭窗口时候的处理函数 */ + +private: + +}; + +#endif // WIDGET_H diff --git a/app/QUVCTest/widget.ui b/app/QUVCTest/widget.ui new file mode 100755 index 0000000..81c6246 --- /dev/null +++ b/app/QUVCTest/widget.ui @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/buildroot/configs/rockchip_rv1126_rv1109_facial_gate_defconfig b/buildroot/configs/rockchip_rv1126_rv1109_facial_gate_defconfig old mode 100644 new mode 100755 index 71e9632..55c7442 --- a/buildroot/configs/rockchip_rv1126_rv1109_facial_gate_defconfig +++ b/buildroot/configs/rockchip_rv1126_rv1109_facial_gate_defconfig @@ -24,6 +24,7 @@ BR2_PACKAGE_RKMEDIA_ANR=y BR2_PACKAGE_RKMEDIA_AEC=y BR2_PACKAGE_RKMEDIA_EXAMPLES=y BR2_PACKAGE_QFACIALGATE=y +BR2_PACKAGE_QUVCTEST=y # BR2_PACKAGE_MINIGUI_SOFTWARE_SCALE is not set BR2_PACKAGE_RKNPU_USE_MINI_DRIVER=y BR2_PACKAGE_RKFACIAL_USE_WEB_SERVER=y diff --git a/buildroot/package/rockchip/Config.in b/buildroot/package/rockchip/Config.in old mode 100644 new mode 100755 index 6735cdc..5f381b9 --- a/buildroot/package/rockchip/Config.in +++ b/buildroot/package/rockchip/Config.in @@ -180,6 +180,7 @@ source "package/rockchip/carmachine/Config.in" source "package/rockchip/gallery/Config.in" source "package/rockchip/QLauncher/Config.in" source "package/rockchip/QFacialGate/Config.in" +source "package/rockchip/QUVCTest/Config.in" source "package/rockchip/settings/Config.in" source "package/rockchip/qcamera/Config.in" source "package/rockchip/qfm/Config.in" diff --git a/buildroot/package/rockchip/QUVCTest/Config.in b/buildroot/package/rockchip/QUVCTest/Config.in new file mode 100755 index 0000000..45cb896 --- /dev/null +++ b/buildroot/package/rockchip/QUVCTest/Config.in @@ -0,0 +1,4 @@ +config BR2_PACKAGE_QUVCTEST + bool "quvctest" + help + rockemd qt quvctest No newline at end of file diff --git a/buildroot/package/rockchip/QUVCTest/QUVCTest.mk b/buildroot/package/rockchip/QUVCTest/QUVCTest.mk new file mode 100755 index 0000000..26d2a86 --- /dev/null +++ b/buildroot/package/rockchip/QUVCTest/QUVCTest.mk @@ -0,0 +1,23 @@ +################################################################################ +# +# QUVCTest +# +################################################################################ + +QUVCTEST_VERSION = 1.0 +QUVCTEST_SITE = $(TOPDIR)/../app/QUVCTest +QUVCTEST_SITE_METHOD = local + +QUVCTEST_LICENSE = Apache V2.0 +QUVCTEST_LICENSE_FILES = NOTICE +define QUVCTEST_CONFIGURE_CMDS +cd $(@D); $(TARGET_MAKE_ENV) $(HOST_DIR)/bin/qmake +endef +define QUVCTEST_BUILD_CMDS +$(TARGET_MAKE_ENV) $(MAKE) -C $(@D) +endef + +define QUVCTEST_INSTALL_TARGET_CMDS +$(INSTALL) -D -m 0755 $(@D)/QUVCTest $(TARGET_DIR)/usr/bin/QUVCTest +endef +$(eval $(generic-package)) No newline at end of file |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
rk1126实现BT601输入,输入不带IIC接口的驱动程序
1137 浏览 0 评论
1170 浏览 1 评论
2263 浏览 3 评论
RK3568 Android11让系统ntp校准时间生效,需要设置些什么
3028 浏览 1 评论
5022 浏览 2 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-16 07:08 , Processed in 0.627201 second(s), Total 70, Slave 54 queries .
Powered by 电子发烧友网
© 2015 www.ws-dc.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号