C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > Qt调用相机拍照

Qt实现调用相机进行拍照并进行图像处理

作者:bubiyoushang888

这篇文章主要为大家详细介绍了如何使用Qt实现调用相机进行拍照并进行图像处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

在Qt中调用相机进行拍照并实现图像处理,可以通过结合Qt Multimedia模块和图像处理库(如OpenCV)实现。

一、相机调用与拍照(Qt Multimedia模块)

1.环境配置

在Qt项目文件(.pro)中添加多媒体模块依赖:

QT += multimedia multimediawidgets

2.相机初始化与显示

#include <QCamera>
#include <QCameraViewfinder>
#include <QCameraImageCapture>
#include <QVideoWidget>
// 初始化相机
QCamera* camera = new QCamera(this);
QCameraViewfinder* viewfinder = new QCameraViewfinder(this);
QCameraImageCapture* imageCapture = new QCameraImageCapture(camera);
// 设置预览窗口
camera->setViewfinder(viewfinder);
viewfinder->show(); // 显示预览画面
// 启动相机
camera->start();

3.拍照功能

// 连接抓图信号
connect(imageCapture, &QCameraImageCapture::imageCaptured, [](int id, const QImage& previewImg) {
    // 获取捕获的图像(previewImg可直接处理)
});

// 触发拍照
imageCapture->capture(); // 默认保存到临时文件,或指定路径 capture("path/to/save.jpg");

二、图像处理(结合OpenCV)

1.QImage转OpenCV Mat

#include <opencv2/opencv.hpp>

cv::Mat qimageToMat(const QImage& qimage) {
    cv::Mat mat(qimage.height(), qimage.width(), CV_8UC4, (void*)qimage.bits());
    cv::cvtColor(mat, mat, cv::COLOR_RGBA2BGR); // 转换颜色通道(Qt为RGB,OpenCV需BGR)
    return mat.clone(); // 避免数据共享
}

2.常用处理示例

(1) 灰度化

cv::Mat grayMat;
cv::cvtColor(inputMat, grayMat, cv::COLOR_BGR2GRAY);

(2) 边缘检测(Canny)

cv::Mat edges;
cv::Canny(grayMat, edges, 100, 200); // 阈值可调

(3) 二值化

cv::Mat binary;
cv::threshold(grayMat, binary, 128, 255, cv::THRESH_BINARY);

(4) 保存处理结果

cv::imwrite("processed.jpg", binary); 

3.Mat转QImage显示

QImage matToQImage(const cv::Mat& mat) {
    cv::Mat rgbMat;
    cv::cvtColor(mat, rgbMat, cv::COLOR_BGR2RGB); // OpenCV BGR转Qt RGB
    return QImage(rgbMat.data, rgbMat.cols, rgbMat.rows, QImage::Format_RGB888);
}

// 在UI中显示
QLabel* label = new QLabel(this);
label->setPixmap(QPixmap::fromImage(processedQImage));

三、完整流程示例

// 初始化相机
QCamera* camera = new QCamera;
QCameraImageCapture* capture = new QCameraImageCapture(camera);
camera->setViewfinder(new QVideoWidget);
camera->start();

// 拍照并处理
connect(capture, &QCameraImageCapture::imageCaptured, [=](int id, const QImage& img) {
    // 转换为OpenCV Mat
    cv::Mat cvImg = qimageToMat(img);
    
    // 边缘检测
    cv::Mat edges;
    cv::Canny(cvImg, edges, 100, 200);
    
    // 显示结果
    QImage resultImg = matToQImage(edges);
    ui->resultLabel->setPixmap(QPixmap::fromImage(resultImg));
});

// 触发拍照
capture->capture();

四、完整项目结构

项目目录/
├── include/
│   ├── CameraHandler.h   # 封装相机控制
│   └── ImageProcessor.h  # 封装OpenCV处理
├── src/
│   ├── main.cpp          # 主程序
│   ├── CameraHandler.cpp # 相机初始化、拍照
│   └── ImageProcessor.cpp# 图像处理算法
└── ui/                   # Qt Designer界面

以上方案兼容Windows/Linux,若需工业相机(如Basler/映美精),需替换为厂商SDK(参考),但核心处理逻辑相同。

五、方法补充

在 Qt 中调用相机并处理图像,核心是理解 Qt Multimedia API 并选择适合的两种主流方案。

为实现您提到的功能,方案一(Qt 捕获 + OpenCV 处理)是首选的强大组合。您可以根据需求选择以下两种主要方式。

方案概览:选择适合你的路径

技术方案适用场景优点缺点
方案一:纯 Qt (C++/QML)快速集成、界面优先、处理需求简单的应用API 统一,跨平台性好,与 Qt 的 UI 系统无缝结合。图像处理功能相对有限。
方案二:Qt + OpenCV复杂图像处理、计算密集型任务(如人脸识别、缺陷检测)利用 OpenCV 强大的算法库,处理效率高,可实现复杂的视觉效果。集成步骤稍复杂,项目体积增大。

第一步:准备工作:环境与权限

第二步:相机的核心接入与拍照

这部分代码构成了相机应用最基础的UI层,将摄像头画面和拍照按钮组合在一起。

方式一:QML 快速开发 (代码简洁,UI 灵活)

使用 CaptureSession 等类型,可以快速搭建一个功能完整的相机界面。

QML 相机示例

这个示例使用 QML 来布局相机取景器和拍照按钮。

import QtQuick
import QtMultimedia
Rectangle {
    width: 640; height: 480
    CaptureSession {
        id: captureSession
        camera: Camera {       // ① 相机对象,处理设备与参数
            id: camera
            active: true       // 激活摄像头,开始预览
        }
        imageCapture: ImageCapture { // ② 拍照对象,负责捕获图像
            id: imageCapture
            onImageSaved: (id, path) => {
                console.log("图片已保存至:" + path)  // 照片保存后触发的信号
            }
            onErrorOccurred: (id, error, errorString) => {
                console.error("拍照出错:" + errorString) // 必须监听,处理错误
            }
        }
        videoOutput: videoOutput   // ③ 连接输出设备,显示预览
    }
    VideoOutput {                 // 显示摄像头画面的取景器
        id: videoOutput
        anchors.fill: parent
    }
    Button {
        text: "拍照"
        anchors.bottom: parent.bottom
        anchors.horizontalCenter: parent.horizontalCenter
        enabled: imageCapture.readyForCapture // 仅在相机就绪时启用
        onClicked: imageCapture.capture()     // 点击触发拍照
    }
}

注意:对 QML 的 ImageCapture,不需要定义 preview 信号和槽,这是与 C++ 方式的重要区别。

方式二:C++ 灵活控制 (粒度高,处理逻辑强)

C++ 方式允许开发者更精细地控制相机行为,尤其是图像数据的获取和处理。

创建相机和取景器

// 获取默认摄像头并创建对象
QCamera *camera = new QCamera(QCameraInfo::defaultCamera());
// 创建视频取景器控件,用于显示画面
QVideoWidget *viewfinder = new QVideoWidget();
// 将摄像头画面输出到取景器,这是显示画面的关键一步
camera->setViewfinder(viewfinder);

创建拍照对象并处理信号

// 创建拍照控制器,并关联到 camera 对象
QCameraImageCapture *imageCapture = new QCameraImageCapture(camera);

QCameraImageCapture 类提供了两个核心信号。您需要连接相应的槽函数来处理照相机的不同状态。

// 示例:基本拍照流程
// 确保相机已启动
camera->start();
// 触发拍照,照片会默认保存到系统默认的相册或图片目录
imageCapture->capture();

处理内存中的图像数据(适合实时处理):连接 imageCaptured 信号,您可以快速获得 QImage 数据。

处理保存到磁盘的文件(适合存档):连接 imageSaved 信号,在照片写入文件后触发。

启动相机

camera->start();
viewfinder->show();

第三步:捕获并处理图像数据

这是实现 "处理图像" 需求的关键环节。本文的核心知识在于 imageCaptured 信号与 OpenCV 的结合。通过 imageCaptured 信号获取的 QImage 对象,可以无缝传递给 OpenCV 进行处理,实现了 Qt 界面与强大算法库的优势结合。

C++ 代码示例:在内存中获取并处理图像

class ImageProcessor : public QObject
{
    Q_OBJECT
public:
    ImageProcessor() {
        // 假设 camera 和 imageCapture 已经正确初始化
        // 连接捕获到图像数据时的信号
        connect(imageCapture, &QCameraImageCapture::imageCaptured,
                this, &ImageProcessor::handleImageCaptured);
        // 启动相机
        camera->start();
    }
private slots:
    void handleImageCaptured(int id, const QImage &preview) {
        // 此时获得的 preview QImage 还未保存,直接在内存中
        qDebug() << "捕获到图像,尺寸:" << preview.size();
        // --- 在这里对图像进行各种处理 ---
        // 1. 转换为灰度图
        QImage grayImage = preview.convertToFormat(QImage::Format_Grayscale8);
        // 2. 缩放图像
        QImage scaledImage = grayImage.scaled(640, 480, Qt::KeepAspectRatio);
        // --- 使用 OpenCV 处理(如果需要)---
        // 将 QImage 转换为 cv::Mat(前提是项目已集成 OpenCV)
        // cv::Mat mat = cv::Mat(
        //     preview.height(), preview.width(),
        //     CV_8UC3, (uchar*)preview.bits(), preview.bytesPerLine()
        // );
        // cv::cvtColor(mat, mat, cv::COLOR_BGR2GRAY);
        // 显示处理后的图像(例如在一个 QLabel 上)
        // ui->label->setPixmap(QPixmap::fromImage(grayImage));
        // 或者,将处理后的图像保存到文件
        scaledImage.save("processed_image.jpg");
    }
};

操作提示:您可以在 handleImageCaptured 函数中添加任何处理代码。在自定义的 ImageProcessor 类中,可以接收 QImage 并进行一系列 Qt 自带的图像处理操作。

到此这篇关于Qt实现调用相机进行拍照并进行图像处理的文章就介绍到这了,更多相关Qt调用相机拍照内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文