C#+Halcon 图像拼接

2 篇文章 0 订阅
1 篇文章 0 订阅

近期在用线扫相机进行一些视觉检测,针对线扫相机的特性,对其输出的图像进行拼接,例如拼接上一张图像的最后64行到下本次图像中。

最开始的思路是在halcon中进行操作,利用paint_region进行重绘,发现效率极低。后来想起来不就是矩阵操作,数组拷贝之类的操作吗,最后直接在C#中进行拼接,对图像指针进行操作(效率还是不如C++)。分享代码如下:

   /// <summary>
        /// 将两个指针拼接成一个数组
        /// </summary>
        /// <param name="lastPtr">上一次数据指针</param>
        /// <param name="curPtr">本次数据指针</param>
        /// <param name="imgWidth">图片宽度</param>
        /// <param name="imgHeight">图片长度</param>
        /// <param name="concatRowCount">拼接行数</param>
        /// <param name="outputBytes">输出数组</param>
        public static void ConcatGrayIntptr(IntPtr lastPtr, IntPtr curPtr, int imgWidth,
            int imgHeight, int concatRowCount, out byte[] outputBytes)
        {
            outputBytes = new byte[(imgHeight + concatRowCount) * imgWidth];
            IntPtr offsetLastPtr = IntPtr.Zero;
            if (lastPtr != IntPtr.Zero)
            {
                if (IntPtr.Size == sizeof(Int64))
                    offsetLastPtr = new IntPtr(lastPtr.ToInt64() + imgWidth * (imgHeight - concatRowCount));
                else
                    offsetLastPtr = new IntPtr(lastPtr.ToInt32() + imgWidth * (imgHeight - concatRowCount));
            }
            if (offsetLastPtr != IntPtr.Zero)
            {
                System.Runtime.InteropServices.Marshal.Copy(offsetLastPtr, outputBytes, 0, concatRowCount * imgWidth);
            }
            System.Runtime.InteropServices.Marshal.Copy(curPtr, outputBytes, concatRowCount * imgWidth, imgWidth * imgHeight);
        }

        /// <summary>
        /// 把多个指针拼接成一个数组,其中忽略掉重叠部分
        /// </summary>
        /// <param name="ptrs"></param>
        /// <param name="imgWidth"></param>
        /// <param name="imgHeight"></param>
        /// <param name="concatRowCount"></param>
        /// <param name="outputBytes"></param>
        public static void ConcatGrayContinuesIntptr(IntPtr[] ptrs,int imgWidth,int imgHeight,int concatRowCount,out byte[] outputBytes)
        {

            int oneImageSize = imgWidth * (imgHeight - concatRowCount);

            outputBytes = new byte[oneImageSize * ptrs.Length];

            int iCopyIndex = 0;
            foreach(IntPtr ptr in ptrs)
            {
                if (ptr != IntPtr.Zero)
                {
                    IntPtr offsetPtr;
                    if (IntPtr.Size == sizeof(Int64))
                        offsetPtr = new IntPtr(ptr.ToInt64() + imgWidth *  concatRowCount);
                    else
                        offsetPtr = new IntPtr(ptr.ToInt32() + imgWidth *  concatRowCount);

                    System.Runtime.InteropServices.Marshal.Copy(offsetPtr, outputBytes, iCopyIndex, oneImageSize);
                }
              
                iCopyIndex += oneImageSize;
            }
        }


        /// <summary>
        /// 拼接连续的几张图片成一张图片
        /// </summary>
        /// <param name="images">图片集合</param>
        /// <param name="concatRowCount">其中每张图片重合的行数</param>
        /// <param name="concatedImage">拼接后的图片</param>
        /// <returns></returns>
        public static bool ConcatGrayImage(HImage[] images,int concatRowCount,out HImage concatedImage)
        {
            if(images.Length == 0)
            {
                concatedImage = null;
                return false;
            }
            List<IntPtr> ptrs = new List<IntPtr>();
            string type;
            int width = 0, height= 0;
            foreach(HImage img in images)
            {
                if (img == null)
                {
                    ptrs.Add(IntPtr.Zero);
                }
                else
                {
                    IntPtr ptr = img.GetImagePointer1(out type,out width, out height);
                    ptrs.Add(ptr);
                }
            }
            byte[] pixelBytes;
            ConcatGrayContinuesIntptr(ptrs.ToArray(), width, height, concatRowCount, out pixelBytes);


            new Lhxzn.Halcon.CameraImageData2HImage().Transform(
                 new CameraImageDataByte(width, images.Length *(height-concatRowCount), PixelType.Mono8, pixelBytes), out concatedImage);
            return true;
        }

        /// <summary>
        /// 拼接上一张图片的最后几行到本次图片中并输出
        /// </summary>
        /// <param name="lastImage">上一张图片</param>
        /// <param name="curImage">本次的图片</param>
        /// <param name="concatRowCount">需拼接的行数</param>
        /// <param name="concatedImage">输出的图像</param>
        /// <returns></returns>
        public static bool ConcatGrayImage(HImage lastImage, HImage curImage, int concatRowCount, out HImage concatedImage)
        {

            if (curImage == null || (lastImage == null && curImage == null))
            {
                concatedImage = null;
                return false;
            }
            else
            {
                string last_type, cur_type;
                int last_width, last_height, cur_width, cur_height;

                IntPtr lastPtr = IntPtr.Zero;
                if (lastImage != null)
                    lastPtr = lastImage.GetImagePointer1(out last_type, out last_width, out last_height);
                IntPtr curPtr = curImage.GetImagePointer1(out cur_type, out cur_width, out cur_height);

                int new_width = cur_width, new_height = cur_height + concatRowCount;
                byte[] pixelBytes;
                ConcatGrayIntptr(lastPtr, curPtr, cur_width, cur_height, concatRowCount, out pixelBytes);

                DateTime start = DateTime.Now;

                new Lhxzn.Halcon.CameraImageData2HImage().Transform(
                    new CameraImageDataByte(cur_width, new_height, PixelType.Mono8, pixelBytes), out concatedImage);
                double inter = (DateTime.Now - start).TotalMilliseconds;
                return true;
            }

        }

 

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值