警告

本节包含从 C++ 自动翻译到 Python 的代码段,可能包含错误。

相机概述#

相机取景、静态图像捕捉和视频录制。

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

相机功能#

为了使用相机类,需要简要概述相机的运行方式。如果您已经熟悉这些,可以跳到 相机实现细节 。有关相机如何工作的更详细解释,请参阅以下 YouTube 视频。

镜头组件#

摄像头组件的一端是镜头组件(一个或多个镜头,用以聚焦光线到传感器上)。有时可以通过调整对焦和变焦等来移动镜头。它们也可能被固定在一个配置中,以保持对焦和成本之间的良好平衡。

../_images/how-focus-works.gif ../_images/Zoom.gif

某些镜头组件可以自动调整,以便将不同距离的物体保持在对焦状态。这通常是通过测量画框某个特定区域的清晰度,然后调整镜头组件以找到最大清晰度。在某些情况下,相机始终使用画面的中心进行此操作。在其他情况下,相机还可能允许指定此目标对焦区域。以下是一些具有此功能的示例:

  • 面部缩放:使用计算机视觉检测和使用一个或多个面部作为目标。

  • 触摸缩放:在预览屏幕上允许用户手动选择一个区域。

传感器#

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

  • 转换允许持续的时间长度。也称为曝光时间。

  • 光线的亮度。

转换允许的时间越长, resulting图象质量越好。使用闪光灯可以帮助让更多的光线击中传感器,使其更快地将像素转换为数字,从而在相同的时间内提供更好的质量。相反,允许更长的转换时间可以实现更暗环境中的拍照,只要相机保持稳定即可。如果传感器录制过程中相机移动, resulting图象将是模糊的。

图像处理#

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

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

../_images/image_processing.png

在此阶段也可以执行一些“特殊效果”。可以制作黑白、棕褐色或“负片”风格的图像。

久远的记录#

最后,一旦创建了一个焦点准确、曝光和处理的图像,就可以将其有效地应用。相机图像可以通过应用程序代码进一步处理(例如,检测条形码或拼合并成全景图像),或保存为JPEG等常用格式,或制作成电影。许多这些任务都有类来辅助。

相机的实现细节#

检测和选择相机#

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

def checkCameraAvailability():

    if QMediaDevices.videoInputs().count() > 0:
        return True
else:
        return False

使用C++中的 QCamera类别或QML中的 Camera类型访问相机。

当有多个相机可用时,您可以指定使用哪一个。

在C++中

cameras = QMediaDevices.videoInputs()
for cameraDevice in cameras:
    if cameraDevice.description() == "mycamera":
        camera = QCamera(cameraDevice)

在QML中,您可以通过设置 Camera::cameraDevice属性来选择相机。您也可以根据相机的物理位置而不是相机信息来选择相机。这在移动设备上很有用,因为常用有前置摄像头和后置摄像头。

在C++中

camera = QCamera(QCameraDevice.FrontFace)

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

在QML中

如果既没有指定 QCameraDevice)又没有指定位置,则将使用默认相机。在桌面平台上,用户在系统设置中设置默认相机。在移动设备上,通常是后置摄像头为默认相机。您可以使用 defaultVideoInput()或QML中的 MediaDevices .defaultVideoInput来获取默认相机。

预览#

虽然这不是强制性的,但通常很有用能够看到相机指向的是什么。这被称为预览。

根据您是否使用QML或C++,您可以通过多种方式完成此操作。在QML中,您可以使用 Camera和videoOutput一起来监视捕获会话。

在C++中,您的选择取决于您是使用小部件还是QGraphicsView。在所有情况下,我们使用了QVideoWidget类,并且对于QGraphicsVideoItem,它适用于QGraphicsView。

captureSession = QMediaCaptureSession()
camera = QCamera()
captureSession.setCamera(camera)
viewfinder = QVideoWidget()
captureSession.setVideoOutput(viewfinder)
viewfinder.show()
camera.start() # to start the camera

对于高级使用(例如处理预览帧以及检测对象或模式),您也可以使用自己的QVideoSink并将其设置为QMediaCaptureSession的videoOutput。在这种情况下,您将需要通过处理从videoFrameChanged()信号接收到的数据来自己渲染预览图像。

captureSession = QMediaCaptureSession()
camera = QCamera()
captureSession.setCamera(camera)
mySink = QVideoSink()
captureSession.setVideoOutput(mySink)
camera.start()
# MyVideoSink::setVideoFrame(..) will be called with video frames

在移动设备上,预览图像默认情况下以与设备相同的方式显示。因此,当用户旋转设备时,预览图像将在纵向和横向模式之间切换。一旦开始录制,方向将锁定。为了避免糟糕的用户体验,您应该在录制过程中锁定应用程序用户界面的方向。这可以通过使用QWindow的contentOrientation属性来实现。

静态图像#

在设置取景器和找到有摄影价值的东西之后,为了捕捉图像,我们需要初始化一个新的QImageCapture对象。所有需要做的就是启动摄像头并捕捉图像。

captureSession = QMediaCaptureSession()
camera = QCamera()
captureSession.setCamera(camera)
imageCapture = QImageCapture()
captureSession.setImageCapture(imageCapture)
camera.start() # Viewfinder frames start flowing
#on shutter button pressed
imageCapture.capture()

电影#

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

要录制视频,我们需要创建摄像头对象,就像之前一样,但这次我们还初始化了一个媒体录制器对象。

captureSession = QMediaCaptureSession()
camera = QCamera()
captureSession.setCamera(camera)
recorder = QMediaRecorder(camera)
captureSession.setRecorder(recorder)
camera.start()
# setup output format for the recorder
format = QMediaFormat(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的信号可以连接到槽以响应编码过程状态的变化或错误事件。当调用record()时开始录制,这会导致发出recorderStateChanged()信号。录制受QMediaRecorder的记录、停止和暂停槽控制。

控制成像流程#

现在,我们已经介绍了捕捉图像和电影的基础知识,有许多方法可以控制成像流程来实现有趣的技术。正如之前解释的那样,许多物理和电子元素结合起来决定了最终的图像,您可以使用不同的类来控制它们。

聚焦和缩放#

QCamera 允许您通过 FocusMode 枚举来设置通用的对焦策略。 FocusMode 处理诸如 FocusModeAutoFocusModeInfinity 之类的设置。

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

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

曝光、快门速度和闪光灯#

有多种设置会影响照射到相机传感器上的光线量,从而影响图像质量。

自动拍照的主要设置是 曝光模式闪光灯模式 。其他一些设置(例如:ISO设置和曝光时间)通常被自动管理,但在需要时也可以覆盖。

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

图像处理#

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

  • white balance(也称为色温)

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

取消异步操作#

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

示例#

提供了C++和QML示例。

C++ 示例#

Camera-Example

演示如何捕获静态图像或录制视频。

QML 示例#

QML-Camera-Application

此基于 Qt Quick 的应用程序演示了如何使用 API 捕获静态图像或视频。

QML-Video-Recorder

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

参考文档#

C++类#

PySide6.QtMultimedia.QCamera

QCamera类提供了系统摄像头设备的接口。

PySide6.QtMultimedia.QCameraFormat

QCameraFormat类描述了摄像头设备支持的视频格式。

PySide6.QtMultimedia.QCameraDevice

QCameraDevice类提供了关于摄像头设备的一般信息。

PySide6.QtMultimedia.QImageCapture

QImageCapture类用于媒体内容的录制。

QML类型#

qml-qtmultimedia-camera.html

一个与焦点和缩放相关的摄像头设置接口。

qml-qtmultimedia-imagecapture.html

用于捕获摄像头图像的接口。