Halcon视觉之家-Halcon视觉技术论坛

 找回密码
 会员注册

QQ登录

只需一步,快速开始

扫一扫,微信登录

查看: 3467|回复: 4

[资料] C#与Halcon学习——Bitmap转换为HObject

[复制链接]

签到天数: 24 天

连续签到: 4 天

[LV.4]偶尔看看III

4

主题

55

帖子

741

积分

Rank: 6Rank: 6

积分
741
发表于 2020-6-18 15:16:50 | 显示全部楼层 |阅读模式

51Halcon诚邀您的加入,专注于机器视觉开发与应用技术,我们一直都在努力!

您需要 登录 才可以下载或查看,没有账号?会员注册

x
前两天掉进一个大坑,记录一下。写接口的时候要求输入为Image或Bitmap的数据类型,所以在用Halcon处理之前要先把它们编程Hobject的数据类型,在网上搜了一下相关的转换方法,大多是先利用了BitmapData中的LockBits和UnLockBits,取出位图的存储首地址,然后再利用Halcon里的GenImage系列函数根据位图地址创建一个新的HObject。根据这种方法我对图像类型进行了转换,然后就发现原来的算法不起作用了,将转换后的图像用Halcon打开,发现变成了如下这样。

原图

原图

图像扭曲

图像扭曲

整个图就已经扭曲了。。

产生这种结果的代码如下:

public void Bitmap2HObjectBpp8(Bitmap SrcImage, out HObject image)
        {
            try
            {
                Point po = new Point(0, 0);
                Size so = new Size(SrcImage.Width, SrcImage.Height);//template.Width, template.Height
                Rectangle ro = new Rectangle(po, so);

                Bitmap DstImg = new Bitmap(SrcImage.Width, SrcImage.Height, PixelFormat.Format8bppIndexed);
                DstImg = SrcImage.Clone(ro, PixelFormat.Format8bppIndexed);

                Rectangle rect = new Rectangle(0, 0, DstImg.Width, DstImg.Height);
                BitmapData srcBmpData = DstImg.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
                HOperatorSet.GenImage1(out image, "byte", DstImg.Width, DstImg.Height, srcBmpData.Scan0);
                DstImg.UnlockBits(srcBmpData);

            }
            catch (Exception ex)
            {
                image = null;
            }
        }
最开始以为是图像的位数导致的,然后就把所有的图像转为Format8bppIndexed型,还是存在这个问题,就又仔细去看了GenImage1的文档,里面有一句话是Care must be taken not to truncate 64-bit pointers on 64-bit architectures,以为是指针有问题,弄了半天也搞懂为什么。然后偶然间发现这个转换方法对某些图是起作用的,然后看了图的尺寸为4032*3024(在此感谢上苍感谢我的手机。。),发现4032是64的倍数,此刻便开始怀疑这种方法的遍历是不是并非想象中的那样。

于是把目标转移到Scan0上,确实它是位图的首地址,而GenImage1里提到The pixels in PixelPointer are stored line-sequentially,在我们的结果中可以看到一条明显的分割线。

明显有条线

明显有条线



因此猜测是扫描的问题,去数了一下图中黑线在每一行的像素。。发现是delta=64*n-width,其中delta的取值范围是0~3,在此基本就真相大白了,去查了一下BitmapData类,发现其中的有一个属性是Stride,也就是扫描一行的字节数,它是4的倍数,所以说如果按照这个顺序来赋值内存的话,对于宽度不是64倍数的图片来说,不仅会丢失信息,还会造成图片的扭曲,并产生一个黑线。所以在使用GenImage系列的函数时,我们不能直接用Bitmap里面的Scan0指针。

对相关代码进行修改:

public static HObject BitmapToHImage(Bitmap SrcImage)
        {
            HObject Hobj;
            HOperatorSet.GenEmptyObj(out Hobj);

            Point po = new Point(0, 0);
            Size so = new Size(SrcImage.Width, SrcImage.Height);//template.Width, template.Height
            Rectangle ro = new Rectangle(po, so);

            Bitmap DstImage = new Bitmap(SrcImage.Width, SrcImage.Height, PixelFormat.Format8bppIndexed);
            DstImage = SrcImage.Clone(ro, PixelFormat.Format8bppIndexed);

            int width = DstImage.Width;
            int height = DstImage.Height;

            Rectangle rect = new Rectangle(0, 0, width, height);
            System.Drawing.Imaging.BitmapData dstBmpData =
                DstImage.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);//pImage.PixelFormat
            int PixelSize = Bitmap.GetPixelFormatSize(dstBmpData.PixelFormat) / 8;
            int stride = dstBmpData.Stride;

            //重点在此
            unsafe
            {
                int count = height * width;
                byte[] data = new byte[count];
                byte* bptr = (byte*)dstBmpData.Scan0;
                fixed (byte* pData = data)
                {
                    for (int i = 0; i < height; i++)
                        for (int j = 0; j < width; j++ )
                            {
                                 data[i * width + j ] = bptr[i * stride + j];
                            }
                    HOperatorSet.GenImage1(out Hobj, "byte", width, height, new IntPtr(pData));
                }
            }

            DstImage.UnlockBits(dstBmpData);

            return Hobj;
        }
修改之后,就可以发现转换的结果没有问题啦!同样的方法也可以用在转换24位彩色图像上,只要记得这个Stride就行了。。
3.png
4.png

C#与Halcon学习——Bitmap转换为HObject.pdf

1.02 MB, 下载次数: 92, 下载积分: 金币 -2

该用户从未签到

0

主题

28

帖子

639

积分

Rank: 3

积分
639

切换助手验证会员

发表于 2020-6-20 08:06:55 | 显示全部楼层
可以的。。。。。。。。。。

该用户从未签到

0

主题

20

帖子

49

积分

Rank: 1

积分
49

切换助手验证会员

发表于 2020-10-24 10:32:32 | 显示全部楼层
不明觉厉,学习学习

该用户从未签到

0

主题

24

帖子

40

积分

Rank: 6Rank: 6

积分
40
发表于 2020-12-14 10:15:10 | 显示全部楼层
厉害啊,大神

该用户从未签到

0

主题

10

帖子

22

积分

Rank: 1

积分
22
发表于 2021-1-21 22:42:52 | 显示全部楼层
不明觉厉,学习学习
您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

视觉培训招生

建议您使用Chrome、Firefox、Edge、360、IE10以上等主流浏览器浏览本论坛

算子查询| 申请友链| 小黑屋| 手机版| Archiver| 业务支持|

© 2015-2021 Halcon视觉之家  X3.4  粤ICP备15095995号 粤公网安备44030602000670号

本站已安全运行:

快速回复 返回顶部 返回列表