c#与halcon学习——对采集视频流的实时处理及显示

      最近由于项目需求,需要对相机采集的图像进行实时的处理并及时反馈信息,其中第一步就是对采集目标进行校正。由于我们的相机是斜拍,且处理对象在一次检测完之后需要更换(型号、大小、位置等),而我们的拍摄背景又比较杂乱,因此难以对目标进行准确的分割,所以我准备采用一种比较蠢的方法,因为目标是矩形,所以在每次更换对象之后先人为选择四个角点,作为校正的基准点。校正完毕后,再进行后续的处理工作。为了后期方便测试,领导让我学着自己写个小软件,然后过程中就开始遇到问题了。

      这个问题就是,我在采集每一帧图像,然后处理后怎么在另一个窗口实时的进行显示。其实很简单呗,就是新开个线程嘛,但是之前没怎么接触过这类问题,网上资料又比较少,因此就自己摸摸索索搞了好几天才出结果。

      我们先看一下效果。我要将这张图里的宝可梦手机壳进行校正并实时显示。

 

下面贴几个实现的方法。

1.校正算法。OutCorrectedImage。halcon中的一个函数就可以解决了,这个问题便不多赘述。

2.在何处进行校正。这里我是在采集视频的回调函数里进行的。当触发了校正按钮之后,直接在此进行处理。

if (m_bCorrect == true)
                {
                    IntPtr pRaw8Buffer = objIBaseData.ConvertToRaw8(GX_VALID_BIT_LIST.GX_BIT_0_7);

                    int width = (int)(objIBaseData.GetWidth());
                    int height = (int)(objIBaseData.GetHeight());
                    HOperatorSet.GenImage1(out ho_image, "byte", width, height, pRaw8Buffer);
                    
                    //根据控件大小计算真实的坐标
                    HTuple hv_zoomPRow = hv_PRow * (height / PictureBoxHeight);
                    HTuple hv_zoomPCol = hv_PCol * (width / PictureBoxWidth);

                    ho_TransImage = m_mathImage.OutCorrectedImage(ho_image, hv_zoomPRow, hv_zoomPCol);
                }

3.如何新开一个线程在窗口中显示校正后的视频。这里是直接给picturebox.Image赋值(bmp)来达到显示的目的,我尝试过直接显示HObject的方法,不能成功,图像总是会被缩小显示在控件的左上角,至今不知道是怎么回事。。。

        private void m_btnCorrect_Click(object sender, EventArgs e)
        {
            if (hv_PCol.Length == 4)
            {
                camera.StartCorrect(hv_PRow, hv_PCol);
            }

            Thread showimage = new Thread(show);
            showimage.Start();
        }

       //开一个代理

        public delegate void ShowImage(HObject ho_image);

        public void showImage(HObject ho_image)
        {
            if (this.InvokeRequired)
            {
                ShowImage show = new ShowImage(showImage);
                this.Invoke(show, ho_image );
            }
            else
            {
                Bitmap correct;
                HObject2Bpp8(ho_image, out correct);

                //显示控件必须要refresh,不然无法显示
                this.m_picShowCorrectImage.Refresh();
                this.m_picShowCorrectImage.Image = correct;
            }
        }

        private void show()
        {
            while (camera.ho_TransImage != null)
            {
                System.Threading.Thread.Sleep(10);
                showImage(camera.ho_TransImage);
            }
        }

        //如何将灰度HObject图像转化为bmp

        [DllImport("kernel32.dll")]
        public static extern void CopyMemory(int Destination, int add, int Length);
        private void HObject2Bpp8(HObject image, out Bitmap res)
        {
            HTuple hpoint, type, width, height;

            const int Alpha = 255;
            int[] ptr = new int[2];
            HOperatorSet.GetImagePointer1(image, out hpoint, out type, out width, out height);

            res = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
            ColorPalette pal = res.Palette;
            for (int i = 0; i <= 255; i++)
            {
                pal.Entries[i] = Color.FromArgb(Alpha, i, i, i);
            }
            res.Palette = pal;
            Rectangle rect = new Rectangle(0, 0, width, height);
            BitmapData bitmapData = res.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
            int PixelSize = Bitmap.GetPixelFormatSize(bitmapData.PixelFormat) / 8;
            ptr[0] = bitmapData.Scan0.ToInt32();
            ptr[1] = hpoint.I;
            if (width % 4 == 0)
                CopyMemory(ptr[0], ptr[1], width * height * PixelSize);
            else
            {
                for (int i = 0; i < height - 1; i++)
                {
                    ptr[1] += width;
                    CopyMemory(ptr[0], ptr[1], width * PixelSize);
                    ptr[0] += bitmapData.Stride;
                }
            }
            res.UnlockBits(bitmapData);

        }

 

       好了,以上就是这段时间遇到问题的解决方法,可能不是很完善,后续进一步改进吧~~

展开阅读全文

没有更多推荐了,返回首页