摄像机概述

Qt Multimedia API 提供了大量与摄像头相关的类,因此您可以访问移动设备摄像头或网络摄像头中的图像和视频。有 C++ 和 QML API 可用于常见任务。

摄像头功能

为了使用摄像头类,需要对摄像头的工作方式做一个简单的概述。如果您已对此有所了解,则可跳至摄像机实现细节。如需更详细地了解摄像机的工作原理,请参阅以下 YouTube 片段。

镜头组件

相机组件的一端是镜头组件(一个或多个镜头,用于将光线聚焦到传感器上)。镜头本身有时可以移动,以调整焦距和变焦等。它们也可以固定排列,以便在保持焦距和成本之间取得良好平衡。

聚焦工作原理动画

有些镜头组件可以自动调整,以便对距离摄像机不同距离的物体保持对焦。这通常是通过测量画面中某一特定区域的清晰度,然后调整镜头组件以找到峰值清晰度来实现的。在某些情况下,摄像机会始终使用画面的中心点来实现这一点。在其他情况下,摄像机也可以指定目标对焦区域。这种功能的一些示例包括

  • 面部变焦:使用计算机视觉来检测并使用一张或多张人脸作为目标。
  • 触摸缩放:使用户能够通过预览屏幕手动选择一个区域。

传感器

光线到达传感器后,会被转换成数字像素。这一过程取决于很多因素,但最终归结为两点:

  • 转换时间的长短。也称为曝光时间。
  • 光线的亮度。

转换时间越长,图像质量越好。使用闪光灯可以让更多的光线照射到传感器上,使其更快地转换像素,从而在相同的时间内获得更好的画质。反之,只要相机保持稳定,允许较长的转换时间可以让您在较暗的环境中拍摄照片。如果在传感器记录时相机移动,拍摄出来的图像就会模糊。

图像处理

图像被传感器捕捉后,相机固件会对其执行各种图像处理任务,以补偿各种传感器特性、当前光线和所需的图像属性。较快的传感器像素转换时间可能会产生数字噪点,因此可根据相机传感器设置进行一定的图像处理以消除噪点。

在这一阶段,还可以调整图像的颜色,以补偿不同的光源--荧光灯和太阳光会给同一物体带来截然不同的外观,因此可以根据图像的白平衡(由于光源的色温不同)来调整图像。

5 个各种图像处理技术的例子。

在这一阶段还可以进行某些形式的 "特效 "处理。可以制作黑白、棕褐色或 "底片 "风格的图像。

为后人记录

最后,经过完美对焦、曝光和处理的图像就可以派上用场了。相机图像可以通过应用代码进一步处理(例如,检测条形码或拼接全景图像),或保存为 JPEG 等常用格式,或用于制作电影。这些任务中的许多都有类来协助完成。

相机实现细节

检测和选择相机

在使用相机 API 之前,应检查运行时是否有相机可用。如果没有可用的相机,则可以禁用应用程序中与相机相关的功能。要在 C++ 中执行此检查,请使用QMediaDevices::videoInputs() 函数,如下例所示:

bool checkCameraAvailability()
{
    if (QMediaDevices::videoInputs().count() > 0)
        return true;
    else
        return false;
}

使用 C++ 中的QCamera 类或 QML 中的Camera 类型访问摄像头。

当有多个摄像头时,可以指定使用哪一个。

在 C++ 中:

const QList<QCameraDevice> cameras = QMediaDevices::videoInputs();
for (const QCameraDevice &cameraDevice : cameras) {
    if (cameraDevice.description() == "mycamera")
        camera = new QCamera(cameraDevice);
}

在 QML 中,您可以通过设置Camera::cameraDevice 属性来选择摄像机。您还可以通过摄像头在系统中的物理位置而不是摄像头信息来选择摄像头。这对移动设备很有用,因为它们通常有一个前置摄像头和一个后置摄像头。

在 C++ 中:

camera = new QCamera(QCameraDevice::FrontFace);

在 QML 中,您可以设置Camera cameraDevice 属性。可通过MediaDevices.videoInputs 检索可用的摄像机。

在 QML 中:

Camera {
    position: Camera.FrontFace
}

如果未指定QCameraDevice 和位置,将使用默认摄像机。在桌面平台上,默认摄像头由用户在系统设置中设定。在移动设备上,后置摄像头通常是默认摄像头。您可以使用QMediaDevices::defaultVideoInput() 或 QML 中的MediaDevices.defaultVideoInput 获取默认摄像头。

预览

虽然严格来说并无必要,但能看到摄像头指向的内容往往很有用。这就是所谓的预览。

根据您使用的是 QML 还是 C++,您可以通过多种方式来实现这一点。在 QML 中,您可以同时使用Camera 和 videoOutput 来监控 captureSession。

Item {
    VideoOutput {
        id: output
        anchors.fill: parent
    }
    CaptureSession {
        videoOutput: output

        Camera {
            // You can adjust various settings in here
        }
    }
}

在 C++ 中,您的选择取决于使用的是 widgets 还是QGraphicsView 。在 widgets 的情况下使用QVideoWidget 类,在QGraphicsView 的情况下使用QGraphicsVideoItem

QMediaCaptureSession captureSession;
camera = new QCamera;
captureSession.setCamera(camera);
viewfinder = new QVideoWidget;
captureSession.setVideoOutput(viewfinder);
viewfinder->show();

camera->start(); // to start the camera

对于高级用法(如在预览帧到来时对其进行处理,从而实现对物体或图案的检测),您也可以使用自己的QVideoSink ,并将其设置为QMediaCaptureSession 的 videoOutput。在这种情况下,您需要通过处理从 videoFrameChanged() 信号接收到的数据来自行渲染预览图像。

QMediaCaptureSession captureSession;
camera = new QCamera;
captureSession.setCamera(camera);
mySink = new QVideoSink;
captureSession.setVideoOutput(mySink);

camera->start();
// MyVideoSink::setVideoFrame(..) will be called with video frames

在移动设备上,预览图像的默认方向与设备的方向一致。因此,当用户旋转设备时,预览图像将在纵向和横向模式之间切换。一旦开始录制,方向将被锁定。为了避免糟糕的用户体验,还应在录制时锁定应用程序用户界面的方向。这可以通过QWindowcontentOrientation 属性来实现。

静态图像

在设置好取景器并找到合适的拍摄对象后,我们需要初始化一个新的QImageCapture 对象来捕捉图像。然后只需启动相机并捕捉图像即可。

QMediaCaptureSession captureSession;
camera = new QCamera;
captureSession.setCamera(camera);
imageCapture = new QImageCapture;
captureSession.setImageCapture(imageCapture);

camera->start(); // Viewfinder frames start flowing

//on shutter button pressed
imageCapture->capture();

电影

前面我们看到的代码允许捕捉静态图像。录制视频需要使用QMediaRecorder 对象。

要录制视频,我们需要像以前一样创建一个摄像机对象,但这次除了创建一个取景器外,我们还要初始化一个媒体录制器对象。

QMediaCaptureSession captureSession;
camera = new QCamera;
captureSession.setCamera(camera);
recorder = new QMediaRecorder(camera);
captureSession.setRecorder(recorder);

camera->start();

// setup output format for the recorder
QMediaFormat format(QMediaFormat::MPEG4);
format.setVideoCodec(QMediaRecorder::VideoCodec::H264);
format.setAudioCodec(QMediaRecorder::AudioCodec::MP3);
recorder->setMediaFormat(settings);

//on shutter button pressed
recorder->record();

// sometime later, or on another press
recorder->stop();

来自QMediaRecorder的信号可以连接到插槽,以便对编码过程的状态变化或错误事件做出反应。当调用QMediaRecorder::record() 时,记录开始。这会导致发出recorderStateChanged() 信号。录制由QMediaRecorder 的 record()、stop() 和 pause() 插槽控制。

控制成像管道

既然已经介绍了捕捉图像和影片的基础知识,那么就有许多方法来控制成像流水线,以实现一些有趣的技术。如前所述,多个物理和电子元素结合在一起决定了最终的图像,您可以使用不同的类来控制它们。

对焦和变焦

QCamera FocusMode FocusMode 处理 和 等设置。QCamera::FocusModeAuto QCamera::FocusModeInfinity

对于支持该功能的相机硬件,QCamera::FocusModeAutoNear 允许对靠近传感器的物体成像。这在条形码识别或名片扫描等应用中非常有用。

除了对焦,QCamera 还允许您使用setZoomFactor() 或zoomTo() 控制任何可用的变焦功能。可用的缩放范围可能有限,也可能完全固定为 1:1。可使用minimumZoomFactor() 和maximumZoomFactor() 检查允许的范围。

曝光、快门速度和闪光灯

有许多设置会影响照相机传感器的光量,从而影响图像质量。

自动拍摄图像的主要设置是exposure modeflash mode 。其他一些设置(如 ISO 设置和曝光时间)通常是自动管理的,但也可以根据需要进行重设。

最后,您可以使用该类来控制闪光灯硬件(如果有的话)。在某些情况下,该硬件还可以兼作手电筒。

图像处理

通过QCamera 类,您可以调整流水线的图像处理部分。这些设置包括

大多数相机都支持所有这些设置的自动设置,因此除非用户需要特定的设置,否则不需要进行调整。

取消异步操作

图像捕捉和自动对焦等各种操作都是异步进行的。只要相机支持,通常可以通过启动新操作来取消这些操作。

示例

我们提供 C++ 和 QML 示例。

C++ 示例

Camera Example

展示如何捕捉静态图像或录制视频。

QML 示例

QML Camera Application

这个基于Qt Quick 的应用程序展示了如何使用 API 捕捉静态图像或视频。

QML Video Recorder

使用Qt Quick.NET 录制音频和视频

参考文档

C++ 类

QCamera

系统摄像头设备接口

QCameraDevice

有关摄像设备的一般信息

QCameraFormat

描述摄像设备支持的视频格式

QImageCapture

用于录制媒体内容

QML 类型

Camera

与对焦和变焦相关的摄像机设置界面

ImageCapture

捕捉摄像机图像的界面

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.