从相机寄存器获取图像
Getting Image from camera registers
我正在为我的大学开发一个简单的成像软件,我 运行 在从相机获取图像时遇到了烦人的问题。
有一个用于相机 Apogee Alta U57 的 .dll COM 库(库和文档在这里:http://www.ccd.com/downloads.html)并且有两种可能的方法从相机获取图像(前提是图像已准备好):
使用 "ICamera2 camera.image",其中 returns
"Returns a 2D SAFEARRAY, of type LONG (4 bytes per
element) or INTEGER (2 bytes per element), which contains
the image data. The type of data (LONG or INTEGER)
returned is controlled by the associated property of
ConvertShortToLong."
使用 "ICamera2.GetImage(int pImageBuffer)" 描述为:
Returns a pointer to 16 bit, unsigned short data located
in memory. The image data region should be allocated by the
application prior to calling this method.
我在使用第二种方法时很困惑,因为 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 个小时一直在编码),也许我遗漏了一些东西:(
好的,看起来您的 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;
}
}
}
我正在为我的大学开发一个简单的成像软件,我 运行 在从相机获取图像时遇到了烦人的问题。 有一个用于相机 Apogee Alta U57 的 .dll COM 库(库和文档在这里:http://www.ccd.com/downloads.html)并且有两种可能的方法从相机获取图像(前提是图像已准备好):
使用 "ICamera2 camera.image",其中 returns
"Returns a 2D SAFEARRAY, of type LONG (4 bytes per element) or INTEGER (2 bytes per element), which contains the image data. The type of data (LONG or INTEGER) returned is controlled by the associated property of ConvertShortToLong."
使用 "ICamera2.GetImage(int pImageBuffer)" 描述为:
Returns a pointer to 16 bit, unsigned short data located in memory. The image data region should be allocated by the application prior to calling this method.
我在使用第二种方法时很困惑,因为 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 个小时一直在编码),也许我遗漏了一些东西:(
好的,看起来您的 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;
}
}
}