C#的bitmap的图像转halcon图像,在网上查找有一些直接使用bitmapdata数据给hoject,然后使用HOperatorSet.GenImageInterleaved或者HOperatorSet.GenImage1去生成。方法经过测试有一些问题,这种方法并不是所有的图片都通用,一些图片生成出来后会变成斜的。如下图:
但是通过观察图片可以看出一些规律,就是图片的斜对角有一根很明显的切割线,图片也可以看出是图片的每一行后面都多了一个像素,一直累计导致现在这个样子 。
查找BitmapData类介绍,其中的有一个属性是Stride,也就是扫描一行的字节数,它是4的倍数,因此在行的字节数不满足这个条件时,会对行进行补充。所以说如果按照这个顺序来赋值内存的话,对于宽度不是4倍数的图片来说,不仅会丢失信息,还会造成图片的扭曲,并产生一个黑线。至此图片扭曲的问题了解了,所以需要对程序进行一些修改。
8位bitmap:
public void Bitmap8ToHobject(Bitmap bmp, out HObject ho_img)
{
int height = bmp.Height;//图像的高度
int width = bmp.Width;//图像的宽度
Rectangle imgRect = new Rectangle(0, 0, width, height);
BitmapData bitData = bmp.LockBits(imgRect, ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
int stride = bitData.Stride;
unsafe
{
int count = height * width;
byte[] data = new byte[count];
byte* bptr = (byte*)bitData.Scan0;
fixed (byte* pData = data)
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
//舍去stride填充的部分
data[i * width + j] = bptr[i * stride + j];
}
}
HOperatorSet.GenImage1(out ho_img, "byte", width, height, new IntPtr(pData));
}
}
}
24位bitmap:
public void Bitmap24ToHobject(Bitmap bmp, out HObject ho_img)
{
int height = bmp.Height;//图像的高度
int width = bmp.Width;//图像的宽度
Rectangle imgRect = new Rectangle(0, 0, width, height);
BitmapData bitData = bmp.LockBits(imgRect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
int stride = bitData.Stride;
unsafe
{
//24位的BitMap每个像素三个字节
int count = height * width * 3;
byte[] data = new byte[count];
byte* bptr = (byte*)bitData.Scan0;
fixed (byte* pData = data)
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width * 3; j++)
{
//舍去stride填充的部分
data[i * width * 3 + j] = bptr[i * stride + j];
}
}
HOperatorSet.GenImageInterleaved(out ho_img, new IntPtr(pData), "bgr", bmp.Width, bmp.Height, 0, "byte", bmp.Width, bmp.Height, 0, 0, -1, 0);
}
}
}