📜  如何统一获取相机的位置 - C# (1)

📅  最后修改于: 2023-12-03 15:24:53.419000             🧑  作者: Mango

如何统一获取相机的位置 - C#

在进行相机相关开发或应用时,经常需要获取相机的位置信息,以便进行相应的操作。本文将介绍如何在C#中统一获取相机的位置信息。

方案

在C# 中获取相机位置信息有多种方式,以下是常用的两种方式:

  1. 使用Windows API函数

使用 GetDeviceCaps 函数可以获取设备的位置信息。

[DllImport("gdi32.dll")]
static extern int GetDeviceCaps(IntPtr hdc, int nIndex);

public static Point GetCameraPosition(string cameraName)
{
    Point cameraPosition = new Point();
    using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero))
    {
        IntPtr hdc = graphics.GetHdc();
        // 设备位置索引 nDevNum = -4
        cameraPosition.X = GetDeviceCaps(hdc, -4);
        // 设备位置索引 nDevNum = -5
        cameraPosition.Y = GetDeviceCaps(hdc, -5);
        graphics.ReleaseHdc(hdc);
    }
    return cameraPosition;
}
  1. 使用 DirectShow

使用 DirectShow 可以方便地获取相机的位置信息。

using DirectShowLib;
using System.Runtime.InteropServices;

public static Point GetCameraPosition(string cameraName)
{
    Point cameraPosition = new Point();
    IFilterGraph2 filterGraph = null;
    ICaptureGraphBuilder2 captureGraphBuilder = null;
    IBaseFilter baseFilter = null;
    DsDevice[] devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
    foreach (DsDevice device in devices)
    {
        if (device.Name == cameraName)
        {
            int hr = 0;
            filterGraph = new FilterGraph() as IFilterGraph2;
            captureGraphBuilder = new CaptureGraphBuilder2() as ICaptureGraphBuilder2;
            baseFilter = null;
            try
            {
                hr = captureGraphBuilder.SetFiltergraph(filterGraph);
                hr = filterGraph.AddSourceFilterForMoniker(device.Mon, null, device.Name, out baseFilter);
                if (hr == 0)
                {
                    // 获取位置信息
                    IAMAnalogVideoDecoder pAnalogVideoDecoder = baseFilter as IAMAnalogVideoDecoder;
                    if (pAnalogVideoDecoder != null)
                    {
                        AnalogVideoStandard videoStandard;
                        VideoInfoHeader vih;
                        int hr1 = pAnalogVideoDecoder.get_AvailableTVFormats(out videoStandard);
                        if (hr1 == 0)
                        {
                            hr1 = pAnalogVideoDecoder.get_TVFormat(out videoStandard);
                            if (hr1 == 0)
                            {
                                hr1 = pAnalogVideoDecoder.get_CurrentActualFrameRate(out vih);
                                if (hr1 == 0)
                                {
                                    cameraPosition.X = (int)vih.AvgTimePerFrame;
                                }
                                cameraPosition.Y = (int)videoStandard;
                            }
                        }
                    }
                }
            }
            finally
            {
                if (baseFilter != null)
                {
                    Marshal.ReleaseComObject(baseFilter);
                    baseFilter = null;
                }
                if (captureGraphBuilder != null)
                {
                    Marshal.ReleaseComObject(captureGraphBuilder);
                    captureGraphBuilder = null;
                }
                if (filterGraph != null)
                {
                    Marshal.ReleaseComObject(filterGraph);
                    filterGraph = null;
                }
            }
        }
    }
    return cameraPosition;
}

注意:使用 DirectShow 获取设备位置信息需要安装 DirectShow 9 SDK。

结论

通过本文介绍的两种方法,可以实现在 C# 中获取相机的位置信息。其中 directshow 方式需要安装 DirectShow 9 SDK。