摄像头概述

Qt 多媒体 API 提供了一些与摄像头相关类的支持,使您可以从移动设备的摄像头或网络摄像头访问图像和视频。对于常见的任务,提供既有 C++ 也提供 QML API。

摄像头特性

为了使用摄像头类,需要快速了解摄像头的工作方式。如果您已经熟悉此内容,请跳到摄像头实现细节。要了解摄像头如何工作的更详细解释,请观看下面的 YouTube 视频。

镜头组件

镜头组件(一个或多个镜头,用于将光线聚焦到传感器上)位于相机组件的一端。有时可以将镜头移动以调整诸如焦点和缩放之类的参数。镜头也可能被固定在平衡焦点和成本的良好安排中。

"An animation of how focus works"

一些镜头组件可以自动调整,使不同距离的物体保持清晰。通常是通过测量画面中特定区域的清晰度,然后调整镜头组件以找到峰值清晰度。在某些情况下,相机将始终使用画面的中心进行此操作。在其他情况下,相机还可以允许指定目标焦点区域。此功能的例子包括

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

传感器

光线到达传感器后,被转换为数字像素。这个过程可能取决于许多因素,但最终归结为两个关键因素

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

转换允许的时间越长,生成的图像质量越好。使用闪光灯可以帮助更多光线击中传感器,使其可以更快速地转换像素,因此在相同的时间内提供更好的质量。相反,允许更长的转换时间可以让您在较暗的环境中拍照,只要相机保持稳定。如果在传感器记录时相机移动,生成的图像将是模糊的。

图像处理

图像被传感器捕获后,相机固件对它执行各种图像处理任务,以补偿传感器特性、当前光线和所需图像属性。更快的传感器像素转换时间可能会导致数字噪声,因此可以根据摄像头传感器的设置执行一定量的图像处理,以消除噪声。

在此时,图像的颜色也可以调整,以补偿不同的光源 - 荧光灯和阳光给同一个物体带来非常不同的外观,因此可以根据图片的白平衡进行调整(由于光源颜色的不同)。

"5 examples of various image processing techniques."

此阶段还可以执行一些"特殊效果"。可以生成黑白色、棕褐色或“负片”风格的图像。

记录永恒

最后,一旦创建出完美聚焦、曝光和处理的图像,就可以将其用于实际用途。相机图像可以由应用程序代码进一步处理(例如,检测条形码,或拼接全景图像),或保存为常见的格式如JPEG,或用于创建电影。许多这些任务都有相应的类来辅助。

相机实现细节

检测和选择相机

在使用相机API之前,您应该检查运行时是否可用相机。如果没有相机可用,您可以禁用它应用中的相关功能。下面是如何使用以下示例中的QMediaDevices::videoInputs()函数进行此检查的C++代码:

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中,您可以通过设置MediaDevices.videoInputs来设置Camera cameraDevice属性。可用相机可以通过MediaDevices.videoInputs检索。

在QML中

Camera {
    position: Camera.FrontFace
}

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

预览

尽管不是强制性的,但通常很有用能够看到相机所指向的内容。这被称为预览。

根据您是使用QML还是C++,您可以使用多种方法来完成此操作。在QML中,您可以使用Camera和videoOutput一起来监控捕获会话。

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

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

在C++中,您的选择取决于您是否使用小部件,还是QGraphicsView。在widget的情况下,使用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的视频输出。在这种情况下,您需要通过处理从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

在移动设备上,预览图像默认为与设备相同的方向。因此,当用户旋转设备时,预览图像将在竖直和横幅模式之间切换。开始录制后,方向将被锁定。为了避免差的用户体验,在录制时还应锁定应用程序用户界面的方向。这可以通过使用contentOrientation属性QWindow来实现。

静止图像

在设置取景器和找到有摄影价值的东西后,为了捕获图像,我们需要初始化一个新的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::FocusModeAutoQCamera::FocusModeInfinity等设置。

对于支持它的相机硬件,QCamera::FocusModeAutoNear允许对接近传感器的物体进行成像。这在条形码识别或名片扫描等应用程序中很有用。

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

曝光、快门速度和闪光灯

有许多设置会影响击中相机传感器光线量,从而影响产生的图像质量。

自动拍摄的主要设置是曝光模式exposure mode和闪光灯模式flash mode。其他几个设置(如:ISO设置和曝光时间)通常自动管理,但也可以根据需要覆盖。

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

图像处理

QCamera类允许您调整流程中图像处理的部分。这些设置包括:

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

取消异步操作

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

示例

有C++和QML示例可供参考。

C++ 示例

相机示例

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

QML 示例

QML 相机应用程序

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

QML 视频录制器

使用 Qt Quick 进行音频和视频录制。

参考文档

C++ 类

QCamera

系统摄像机设备的接口

QCameraDevice

关于摄像机设备的一般信息

QCameraFormat

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

QImageCapture

用于录制媒体内容

QML 类型

相机

与对焦和缩放相关的相机设置接口

ImageCapture

用于捕获摄像机图像的接口

© 2024 Qt 公司。本文件中的文档贡献包括各自所有者的版权。本文件提供的文档根据自由软件基金会发布的GNU 自由文档许可证版本 1.3 的条款进行许可。Qt 和相应商标是芬兰及/或世界其他国家的 Qt 公司的商标。所有其他商标均属于其各自所有者。