HObject转成Bitmap类型时,经测试转换速度非常慢,因此可以拐个弯,先转成Mat,再从Mat转成Bitmap。
上代码:
public static Mat HImageToMat(HObject hobj)
{
try
{
Mat pImage;
HTuple htChannels;
HTuple cType = null;
HTuple width, height;
width = height = 0;
htChannels = null;
HOperatorSet.CountChannels(hobj, out htChannels);
if (htChannels.Length == 0)
{
return null;
}
if (htChannels[0].I == 1)
{
HTuple ptr;
HOperatorSet.GetImagePointer1(hobj, out ptr, out cType, out width, out height);
pImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1, new Scalar(0));
int Width = width;
unsafe
{
for (int i = 0; i < height; i++)
{
//long step = pImage.Step();
IntPtr start = IntPtr.Add(pImage.Data, i * width);
CopyMemory(start, new IntPtr((byte*)ptr.IP + width * i), (uint)width);
}
}
return pImage;
}
else if (htChannels[0].I == 3)
{
HTuple ptrRed;
HTuple ptrGreen;
HTuple ptrBlue;
HOperatorSet.GetImagePointer3(hobj, out ptrRed, out ptrGreen, out ptrBlue, out cType, out width, out height);
Mat pImageRed = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
Mat pImageGreen = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
Mat pImageBlue = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
pImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC3, new Scalar(0,0,0));
unsafe
{
for (int i = 0; i < height; i++)
{
long step = pImage.Step();
IntPtr startRed = IntPtr.Add(pImageRed.Data, i * width);
IntPtr startGreen = IntPtr.Add(pImageGreen.Data, i * width);
IntPtr startBlue = IntPtr.Add(pImageBlue.Data, i * width);
CopyMemory(startRed, new IntPtr((byte*)ptrRed.IP + width * i), (uint)width);
CopyMemory(startGreen, new IntPtr((byte*)ptrGreen.IP + width * i), (uint)width);
CopyMemory(startBlue, new IntPtr((byte*)ptrBlue.IP + width * i), (uint)width);
}
}
Mat[] multi = new Mat[] { pImageBlue, pImageGreen, pImageRed };
Cv2.Merge(multi, pImage);
pImageRed.Dispose();
pImageGreen.Dispose();
pImageBlue.Dispose();
return pImage;
}
else
{
return null;
}
}
catch (Exception ex)
{
throw ex;
}
}
其中会用到CopyMemory这个函数,需要在方法前声明:
[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
public static extern void CopyMemory(int dest, int src, int count);