opencv 如何使用Python访问笔记本电脑的内置红外网络摄像头?

m1m5dgzv  于 12个月前  发布在  Python
关注(0)|答案(3)|浏览(129)

我试图在Python项目中访问我笔记本电脑的内置红外摄像头(用于windows hello)。我可以使用OpenCV中的VideoCapture类轻松访问正常的RGB摄像头,但无法找到访问红外摄像头的方法。我尝试向VideoCapture类传递不同的索引,但只有“0”起作用,这是正常的摄像头。
有一些方法可以使用Windows API来实现这一点,但是我找不到在Python中访问它的方法。
有些人已经能够在Ubuntu上使用fswebcam访问windows hello相机。
有没有办法使用python访问红外摄像机?也许有一些方法可以使用pywin32与Windows API接口?任何帮助都可以开始使用。或者,有没有类似于Windows的fswebcam的东西可以让我做同样的事情?

6tqwzwtp

6tqwzwtp1#

您提供的示例似乎没有使用win32 API,而是使用了dotnet框架,特别是Windows.Media.Capture.Frames.MediaFrameSourceGroup类。
看起来你可以使用http://pythonnet.github.io/来访问dotnet框架,之后就可以将C#代码移植到Python了。

7ajki6be

7ajki6be2#

我有点晚了,但也许我可以帮助别人。你可以通过WinRT访问红外摄像头。如果你想用Python来做,应该使用一个维护的WinRT替代品winsdk
我遵循了这个教程:Process media frames with MediaFrameReader
我跳过并简化了一些代码部分,但它确实完成了这项工作。捕获的帧显示在OpenCV窗口中。您可以按“q”退出。
你必须注意脚本中的两个常量。camera_image_widthcamera_image_height定义了捕获帧的分辨率。对于我的硬件,它们是640和360。我不知道这是否是预览相机的标准分辨率,它们可能与其他硬件不同。你可以通过在第88行后调用software_bitmap.pixel_heightsoftware_bitmap.pixel_height来确定它们。
必须安装以下Python包:

  • asyncio
  • numpy
  • OpenCV-Python
  • winsdk

以下是整个脚本:

import asyncio
import time
import numpy as np

import cv2

from winsdk.windows.media.capture import MediaStreamType
from winsdk.windows.media.capture import MediaCapture
from winsdk.windows.media.capture import MediaCaptureInitializationSettings
from winsdk.windows.media.capture import MediaCaptureSharingMode
from winsdk.windows.media.capture import MediaCaptureMemoryPreference
from winsdk.windows.media.capture import StreamingCaptureMode

from winsdk.windows.media.capture.frames import MediaFrameSourceGroup
from winsdk.windows.media.capture.frames import MediaFrameSourceInfo
from winsdk.windows.media.capture.frames import MediaFrameSourceKind
from winsdk.windows.media.capture.frames import MediaFrameReader

from winsdk.windows.graphics.imaging import SoftwareBitmap
from winsdk.windows.graphics.imaging import BitmapPixelFormat

from winsdk.windows.storage.streams import Buffer

camera_image_width = 640
camera_image_height = 360

async def main():
    #####  Find the first infra source group  #####

    media_frame_source_groups = await MediaFrameSourceGroup.find_all_async()

    infra_source_group: MediaFrameSourceGroup
    infra_source_info: MediaFrameSourceInfo

    # Iterating through source groups
    for source_group in media_frame_source_groups:
        for source_info in source_group.source_infos:
            if source_info.media_stream_type == MediaStreamType.VIDEO_PREVIEW and source_info.source_kind == MediaFrameSourceKind.INFRARED:
                infra_source_group = source_group
                infra_source_info = source_info

    # Check if there's available infra source
    if infra_source_group is None or infra_source_info is None:
        print("No infra source was found!")
        return

    #####  Getting frames from infra camera  #####

    with MediaCapture() as media_capture:
        # Settings for MediaCapture object
        media_capture_settings = MediaCaptureInitializationSettings()
        media_capture_settings.source_group = infra_source_group
        media_capture_settings.sharing_mode = MediaCaptureSharingMode.EXCLUSIVE_CONTROL
        media_capture_settings.memory_preference = MediaCaptureMemoryPreference.CPU
        media_capture_settings.streaming_capture_mode = StreamingCaptureMode.VIDEO
        await media_capture.initialize_async(media_capture_settings)

        # Init frame reader
        media_frame_reader: MediaFrameReader = await media_capture.create_frame_reader_async(media_capture.frame_sources[infra_source_info.id])
        await media_frame_reader.start_async()

        # Each frame must be dumped into a buffer
        frame_buffer = Buffer(camera_image_width * camera_image_height * 4)

        # Wait for frames
        while True:
            # Capturing with 20fps
            time.sleep(0.05)

            # Get the latest available frame
            media_frame_reference = media_frame_reader.try_acquire_latest_frame()

            # If the frame is null, skip this cycle
            if media_frame_reference is None:
                continue

            # Try to read frame
            with media_frame_reference:
                # Boilerplate bullshit to extract bitmap data
                video_media_frame = media_frame_reference.video_media_frame

                if video_media_frame is None:
                    return
                
                software_bitmap = video_media_frame.software_bitmap

                if software_bitmap is None:
                    return
                
                #####  The bitmap is just fine  #####

                with software_bitmap:
                    # Convert image format
                    grayscale_bitmap = SoftwareBitmap.convert(software_bitmap, BitmapPixelFormat.RGBA8)

                    # Dump image data to byte buffer
                    grayscale_bitmap.copy_to_buffer(frame_buffer)
                    
                    # Create actual OpenCV image from byte buffer
                    image_array = np.frombuffer(frame_buffer, dtype=np.uint8).reshape(camera_image_height, camera_image_width, 4)

                    # If the image is all black, skip showing
                    if cv2.countNonZero(cv2.cvtColor(image_array, cv2.COLOR_RGBA2GRAY)) == 0:
                        continue
                    
                    cv2.imshow('Infrared camera', image_array)
                    
                    if cv2.waitKey(1) == ord('q'):
                        break

        cv2.destroyAllWindows()

asyncio.run(main())

字符串
祝你好运!

t30tvxxf

t30tvxxf3#

您需要访问WinRT API,而不是Win32 API。
使用这个库:https://github.com/Microsoft/xlang/tree/master/src/package/pywinrt/projection,你应该能够从你发布的代码中调用WinRT中必要的部分。

相关问题