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/opencv2

LIBS += /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_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    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数据可能会在将来的某个时间点被修改或释放,而复制的图像则不受这些变化的影响。

好了,下机!!恰饭

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值