当前位置: 首页 > news >正文

ubuntu中QT+opencv在QLable上显示摄像头

ubuntu中QT+opencv在QLable上显示摄像头

饭前的一篇文章吧,写完吃饭走

图像在机器视觉中的重要性是不可忽视的。机器视觉是指计算机利用图像处理技术进行图像识别、分析和理解的科学与技术领域。图像是机器视觉的输入数据,通过分析和处理图像,计算机可以实现对图像中物体、场景等信息的提取和理解。

以下是图像在机器视觉中的重要性的几个方面:

1. 物体识别和分类:图像可以提供丰富的视觉信息,包括物体的形状、颜色、纹理等特征。通过对图像进行分析和处理,机器可以识别和分类不同的物体,实现自动化的物体检测和识别。

2. 场景分析和理解:通过对图像进行分析,可以理解图像所代表的场景。例如,机器可以通过图像识别出室内、室外、城市、乡村等不同的场景,从而为场景的分析和理解提供基础。

3. 图像检索和搜索:通过对图像进行特征提取和相似度计算,机器可以实现对图像的检索和搜索。例如,在图像数据库中搜索与输入图像相似的图像,或者通过输入图像进行目标物体的搜索和定位。

4. 视觉导航和定位:图像可以提供导航和定位所需的视觉信息。通过对图像进行分析,机器可以识别出环境中的特征点或标志物,从而实现室内、室外等不同环境下的定位和导航。

综上所述,图像在机器视觉中具有重要的作用,是实现机器视觉的关键输入数据。通过对图像进行分析和理解,机器可以实现对物体、场景等信息的自动化识别、分类和理解,从而实现各种应用,如智能监控、智能驾驶等。

那么这一切的开始呢,就是使用opencv来实现摄像头的采集

废话不多,我们直接上代码

UI文件的编写

一个开始一个结束,还有一个摄像头参数的显示,但是写出来有BUG(对程序运行没影响)所以就不实现了,都是原名,没有修改对象名

 代码编写

.pro文件

我们 要导入我们的opencv的库

INCLUDEPATH += /usr/local/include/usr/local/include/opencv/usr/local/include/opencv2LIBS += /usr/local/lib/libopencv_*

.h文件

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <QTimer>
#include<QComboBox>
using namespace cv;
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);//QImage MatImageToQt(const Mat &src);~Widget();private slots:void readFarme();void on_pushButton_clicked();void on_pushButton_2_clicked();private:Ui::Widget *ui;VideoCapture cap;Mat src_image;QTimer *timer;QImage *image;};
#endif // WIDGET_H

.cpp文件

#include "widget.h"
#include "ui_widget.h"
#include <opencv2/core.hpp>
#include<opencv2/opencv.hpp>
#include <QPixmap>
#include <QTimer>
using namespace cv;
using namespace std;Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// Mat mypicture = imread("/home/yyy/图片/aa.jpg");// imshow("open",mypicture);// Mat Medianfiltering;// cv::medianBlur(mypicture,Medianfiltering,7);// imshow("new open",Medianfiltering);timer = new QTimer(this);image = new QImage();connect(timer,SIGNAL(timeout()),this,SLOT(readFarme()));}Widget::~Widget()
{delete ui;
}void Widget::readFarme()
{cap.read(src_image);QImage imag = MatImageToQt(src_image);ui->label->setPixmap(QPixmap::fromImage(imag));
}void Widget::on_pushButton_clicked()
{cap.open(0);timer->start(33);
}void Widget::on_pushButton_2_clicked()
{timer->stop();cap.release();ui->label->clear();
}//Mat转成QImage
QImage Widget::MatImageToQt(const Mat &src)
{//CV_8UC1 8位无符号的单通道---灰度图片if(src.type() == CV_8UC1){//使用给定的大小和格式构造图像//QImage(int width, int height, Format format)QImage qImage(src.cols,src.rows,QImage::Format_Indexed8);//扩展颜色表的颜色数目qImage.setColorCount(256);//在给定的索引设置颜色for(int i = 0; i < 256; i ++){//得到一个黑白图qImage.setColor(i,qRgb(i,i,i));}//复制输入图像,data数据段的首地址uchar *pSrc = src.data;//for(int row = 0; row < src.rows; row ++){//遍历像素指针uchar *pDest = qImage.scanLine(row);//从源src所指的内存地址的起始位置开始拷贝n个//字节到目标dest所指的内存地址的起始位置中memcmp(pDest,pSrc,src.cols);//图像层像素地址pSrc += src.step;}return qImage;}//为3通道的彩色图片else if(src.type() == CV_8UC3){//得到图像的的首地址const uchar *pSrc = (const uchar*)src.data;//以src构造图片QImage qImage(pSrc,src.cols,src.rows,src.step,QImage::Format_RGB888);//在不改变实际图像数据的条件下,交换红蓝通道return qImage.rgbSwapped();}//四通道图片,带Alpha通道的RGB彩色图像else if(src.type() == CV_8UC4){const uchar *pSrc = (const uchar*)src.data;QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_ARGB32);//返回图像的子区域作为一个新图像return qImage.copy();}else{return QImage();}
}

重要代码块讲解

//Mat转成QImage
QImage Widget::MatImageToQt(const Mat &src)
{//CV_8UC1 8位无符号的单通道---灰度图片if(src.type() == CV_8UC1){//使用给定的大小和格式构造图像//QImage(int width, int height, Format format)QImage qImage(src.cols,src.rows,QImage::Format_Indexed8);//扩展颜色表的颜色数目qImage.setColorCount(256);//在给定的索引设置颜色for(int i = 0; i < 256; i ++){//得到一个黑白图qImage.setColor(i,qRgb(i,i,i));}//复制输入图像,data数据段的首地址uchar *pSrc = src.data;//for(int row = 0; row < src.rows; row ++){//遍历像素指针uchar *pDest = qImage.scanLine(row);//从源src所指的内存地址的起始位置开始拷贝n个//字节到目标dest所指的内存地址的起始位置中memcmp(pDest,pSrc,src.cols);//图像层像素地址pSrc += src.step;}return qImage;}//为3通道的彩色图片else if(src.type() == CV_8UC3){//得到图像的的首地址const uchar *pSrc = (const uchar*)src.data;//以src构造图片QImage qImage(pSrc,src.cols,src.rows,src.step,QImage::Format_RGB888);//在不改变实际图像数据的条件下,交换红蓝通道return qImage.rgbSwapped();}//四通道图片,带Alpha通道的RGB彩色图像else if(src.type() == CV_8UC4){const uchar *pSrc = (const uchar*)src.data;QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_ARGB32);//返回图像的子区域作为一个新图像return qImage.copy();}else{return QImage();}
}

这段代码的目的是将OpenCV的Mat(矩阵)对象转换为Qt的QImage对象,以便在Qt框架中使用图像数据,如显示在QLabelQPixmap或其他Qt的图形显示组件中。由于OpenCV和Qt处理图像数据的方式有所不同(例如,内存布局、颜色空间等),因此需要进行适当的转换。下面是这段代码的详细讲解:

1. 灰度图像 (CV_8UC1)

  • 构造QImage:对于灰度图像,使用QImage::Format_Indexed8格式构造QImage对象。这种格式使用8位索引到颜色表来存储每个像素的颜色,适用于灰度图像,因为灰度图像可以看作是从黑色到白色的256级颜色深度。
  • 设置颜色表:通过setColorCount(256)setColor(i, qRgb(i,i,i))QImage设置一个包含256个条目的颜色表,每个条目对应一个灰度值(从黑到白)。
  • 数据复制:使用循环遍历Mat对象的每一行,并将灰度数据复制到QImage的相应行中。这里使用memcpy而不是memcmpmemcmp用于比较内存区域,而不是复制)。然而,原代码中错误地使用了memcmp,应该替换为memcpy

2. 彩色图像 (CV_8UC3)

  • 构造QImage:对于三通道(RGB)彩色图像,使用QImage::Format_RGB888格式直接通过Mat对象的数据指针构造QImage。注意,OpenCV默认使用BGR顺序,而Qt的QImage使用RGB顺序,因此需要使用rgbSwapped()方法来交换红色和蓝色通道。

3. 带Alpha通道的彩色图像 (CV_8UC4)

  • 构造QImage:对于四通道(RGBA)图像,使用QImage::Format_ARGB32格式直接通过Mat对象的数据指针构造QImage。这里不需要交换颜色通道,因为OpenCV的RGBA顺序与Qt的ARGB顺序相匹配(除了最后一个通道的位置,但这不影响颜色显示)。
  • 复制图像:虽然这里直接使用Mat的数据指针构造了QImage,但出于安全和稳定性的考虑,使用copy()方法创建了一个QImage的副本。这是因为原始的Mat数据可能会在将来的某个时间点被修改或释放,而复制的图像则不受这些变化的影响。

好了,下机!!恰饭

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • java基于PDF底层内容流的解析对文本内容进行编辑
  • 计算机网络 第三章: 封装成桢和透明传输
  • 通用四期ARM架构银河麒麟桌面操作系统V10【安装、配置FTP服务端】
  • vue国际化
  • 十二,Spring Boot 异常处理(自定义异常页面,全局异常,自定义异常)
  • Golang数据流处理:掌握Reader和Writer接口的技巧
  • C++设计模式——Mediator中介者模式
  • RAII 与 std::lock_guard 在 C++ 中的应用:自动化互斥锁管理与线程安全
  • 【JavaScript】数据结构之字典 哈希表
  • HTML5下<hr>标签的CSS样式定制
  • 关于Linux Makefile的一些函数知识foreach、if、call、origin、shell、error和warning
  • 如何使用myabtis log plugin插件展示出数据库查询语句
  • 【C++11】智能指针
  • STM32常用数据采集滤波算法
  • Java | Leetcode Java题解之第400题第N位数字
  • Java 最常见的 200+ 面试题:面试必备
  • Java超时控制的实现
  • js数组之filter
  • Lucene解析 - 基本概念
  • Material Design
  • 不上全站https的网站你们就等着被恶心死吧
  • 码农张的Bug人生 - 初来乍到
  • 前端 CSS : 5# 纯 CSS 实现24小时超市
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 使用API自动生成工具优化前端工作流
  • hi-nginx-1.3.4编译安装
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • ​Java并发新构件之Exchanger
  • # 移动硬盘误操作制作为启动盘数据恢复问题
  • $NOIp2018$劝退记
  • (13)DroneCAN 适配器节点(一)
  • (26)4.7 字符函数和字符串函数
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (C++二叉树05) 合并二叉树 二叉搜索树中的搜索 验证二叉搜索树
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (k8s中)docker netty OOM问题记录
  • (六)软件测试分工
  • (每日一问)设计模式:设计模式的原则与分类——如何提升代码质量?
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (实测可用)(3)Git的使用——RT Thread Stdio添加的软件包,github与gitee冲突造成无法上传文件到gitee
  • (一)python发送HTTP 请求的两种方式(get和post )
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • (转)拼包函数及网络封包的异常处理(含代码)
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • ./configure、make、make install 命令
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现
  • .Net 代码性能 - (1)
  • .NET/C# 使用反射调用含 ref 或 out 参数的方法
  • .NET设计模式(8):适配器模式(Adapter Pattern)
  • .Net实现SCrypt Hash加密
  • .Net中的设计模式——Factory Method模式