从相机寄存器获取图像
本文关键字:图像 获取 寄存器 相机 | 更新日期: 2023-09-27 17:50:23
我正在为我的大学开发一个简单的成像软件,我在从相机获取图像时遇到了令人讨厌的问题。有一个。dll COM库用于相机Apogee Alta U57(库和文档在这里:http://www.ccd.com/downloads.html),有两种可能的方法从相机获取图像(提供图像准备好):
-
使用"ICamera2相机"。Image ",返回
"返回一个2D SAFEARRAY,类型为LONG(每个4字节)元素)或INTEGER(每个元素2字节),其中包含图像数据。数据类型(LONG或INTEGER)的关联属性控制ConvertShortToLong。"
使用"ICamera2 。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;
}
}
}