从相机寄存器获取图像

本文关键字:图像 获取 寄存器 相机 | 更新日期: 2023-09-27 17:50:23

我正在为我的大学开发一个简单的成像软件,我在从相机获取图像时遇到了令人讨厌的问题。有一个。dll COM库用于相机Apogee Alta U57(库和文档在这里:http://www.ccd.com/downloads.html),有两种可能的方法从相机获取图像(提供图像准备好):

  1. 使用"ICamera2相机"。Image ",返回

    "返回一个2D SAFEARRAY,类型为LONG(每个4字节)元素)或INTEGER(每个元素2字节),其中包含图像数据。数据类型(LONG或INTEGER)的关联属性控制ConvertShortToLong。"

  2. 使用"ICamera2
  3. 。gettimage (int pImageBuffer)",描述为:

    返回指向16位无符号短数据的指针在内存中。图像数据区域应由

在使用第二个方法时我很困惑,因为int != int*,我真的不知道如何传递指针到16位USHORT。我获取图像的简化方法如下所示:

        public unsafe uint[] getImage(int width, int height)
    {
        // Allocating array of image size (width * height)
        // where pixel is size of unsigned int (4 BYTES)
        // possible values: 0 to 4,294,967,295 
        uint[] pixels = new uint[width * height];
        // Gets pointer to allocated array and fixes it, 
        // so that it won't be moved by Garbage Collector
        fixed (uint* ptr = pixels)
        {
            camera.GetImage(ptr);
        }
        return pixels;
    }

有人能解释吗?我真的很累(已经编码了10个小时),也许我错过了一些东西:(

从相机寄存器获取图像

Ok,看起来您的GetImage函数期望您为图像像素分配内存并传递指向该分配内存的指针。当你用完这些内存后,你也有责任释放这些内存。

我认为你需要做的唯一改变是将指针转换为long - GetImage函数需要long,而不是指针(在32位平台上,指针将是32位;在64位平台上,它将是64位)。

// Gets pointer to allocated array and fixes it, 
// so that it won't be moved by Garbage Collector
fixed (uint* ptr = pixels)
{
    long ptrValue = (long) ptr;
    camera.GetImage(ptrValue);
}

这种强制转换不是很好,但它是安全的,因为位的数量对于两个平台都足够。(我怀疑你已经瞄准32位或64位平台了。)

文档说它需要Uint16类型。我认为你应该这样做

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
        [DllImport("Apogee.dll.dll")]
        extern static int CreateInstance(out IntPtr ICamera2Ptr);
        [DllImport("Apogee.dll.dll")]
        extern static void GetImage(ref IntPtr pImageBuffer);
        static void Main(string[] args)
        {
            IntPtr ICamera2Ptr;
            int results = CreateInstance(out ICamera2Ptr);
        }
        static UInt16[] getImage(int width, int height)
        {
            // Allocating array of image size (width * height)
            // where pixel is size of unsigned int (4 BYTES)
            // possible values: 0 to 4,294,967,295 
            // Allocate memory and calculate a byte count 
            //unsigned short *pBuffer = new unsigned short[ ImgXSize * ImgYSize ];
            //unsigned long ImgSizeBytes = ImgXSize * ImgYSize * 2; 
            UInt16[] pixels = new UInt16[width * height];
            IntPtr unmanaged_pPixels = Marshal.AllocHGlobal(Marshal.SizeOf(pixels));
            //// External operations ApogeeCamera->ExternalShutter = true; 
            //ApogeeCamera->ExternalIoReadout = false; 
            //ApogeeCamera->IoPortAssignment = 0x08; 
            // Even though the exposure time will not be used, still call Expose 
            //ApogeeCamera->Expose( 0.001, true ); 
            // Check camera status to make sure image data is ready 
            //while (ApogeeCamera->ImagingStatus != Apn_Status_ImageReady ); 
            // Get the image data from the camera ApogeeCamera->GetImage( (long)pBuffer );

            GetImage(ref unmanaged_pPixels);
            pixels = (UInt16[])Marshal.PtrToStructure(unmanaged_pPixels, typeof(UInt16[]));
            return pixels;

        }
    }
}
​