Halcon图像类HImage转为.NET图像类Bitamap

news/2024/7/21 6:02:07 标签: .net, 图像处理, opencv

在上一篇完成OPENCV 图像类Mat 与.NET图像类Bitamap互相转换之后,本篇博客又给出了Halcon图像类HImage转为.NET图像类Bitamap。不过目前还只能讲彩色三通道图像HImage转为黑白单通道Bitmap。
彩色互转还需要做实验。
另外,鉴于.Net 自身对图像处理有限的功能,将Bitmap转为HImage,也会有相关的方法,需要的可以评论区留言。
作为十分出名的商用计算机视觉库Halcon,本文就给出如何将Halcon图像类HImage转为.NET图像类Bitamap。
本文将转换方法封装成一个函数,输出为Bitmap类型实例。
下面是一个demo,具体如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using HalconDotNet;

namespace HImage与Bitamap互转
{
    public partial class Form1 : Form
    {
        //HDevelopExport cv = new HDevelopExport();
        Thread grabThread;
        public HTuple hv_ExpDefaultWinHandle;
        bool startGrabFlag = false;
        HTuple hv_AcqHandle = new HTuple();
        public static Bitmap bmp;
        //public Bitmap bmp;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //cv.GiveWindow(hWindowControl.HalconWindow);
        }

        private void openCameraBtn_Click(object sender, EventArgs e)
        {
            //cv.OpenCam();
            hv_AcqHandle.Dispose();
            HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb",
                -1, "false", "default", "[0] USB2.0 VGA UVC WebCam", 0, -1, out hv_AcqHandle);
        }

        private void closeCamBtn_Click(object sender, EventArgs e)
        {
            HOperatorSet.CloseFramegrabber(hv_AcqHandle);

        }

        private void startGrabBtn_Click(object sender, EventArgs e)
        {
            grabThread = new Thread(new ThreadStart(GrabNow));
            grabThread.Start();
        }
        private void GrabNow()
        {
            HObject ho_Image = null;
            startGrabFlag = true;
            // Initialize local and output iconic variables 
            HOperatorSet.GenEmptyObj(out ho_Image);
            //Image Acquisition 01: Code generated by Image Acquisition 01
            HOperatorSet.GrabImageStart(hv_AcqHandle, -1);
            while (startGrabFlag == true)
            {
                ho_Image.Dispose();
                HOperatorSet.GrabImageAsync(out ho_Image, hv_AcqHandle, -1);
                pictureBox.Image = Exchange(ho_Image);
                //HOperatorSet.GetImageSize(ho_Image,)
                HOperatorSet.DispObj(ho_Image, hWindowControl.HalconWindow);
                //Image Acquisition 01: Do something
            }

            ho_Image.Dispose();
        }
        private HImage HObjectToHImage(HObject obj)
        {
            HImage img = new HImage();
            HTuple pointer, type, width, heght;
            HOperatorSet.GetImagePointer1(obj, out pointer, out type, out width, out heght);
            //HOperatorSet.GenEmptyObj(out img);
            img.GenImage1(type, width, heght, pointer);
            return img;
        }

        private Bitmap Exchange(HObject ho_Image)
        {
            HImage temp = HObjectToHImage(ho_Image);
            HImage grayImage = temp.Rgb1ToGray();//将彩色图像转为黑白
            string type;//接收图像类型
            int width, height;//接收图像尺寸
            IntPtr pointer = grayImage.GetImagePointer1(out type, out width, out height);
            ColorPalette palette = null;
            Bitmap bitmap = null;
            Bitmap curBitmap = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
            Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
            BitmapData imageData = curBitmap.LockBits(rect, ImageLockMode.ReadOnly, curBitmap.PixelFormat);
            int PixelSize = Bitmap.GetPixelFormatSize(imageData.PixelFormat) / 8;
            //定义用于存储图像数据的Buffer
            byte[] buffer = new byte[curBitmap.Width * curBitmap.Height];
            //将图像数据复制到Buffer内
            System.Runtime.InteropServices.Marshal.Copy(pointer, buffer, 0, buffer.Length);
            unsafe
            {
                //使用不安全代码
                fixed (byte* bytePointer = buffer)
                {
                    bitmap = new Bitmap(curBitmap.Width, curBitmap.Height, curBitmap.Width, PixelFormat.Format8bppIndexed, new IntPtr(bytePointer));
                    palette = bitmap.Palette;
                    for (int Index = 0; Index <= byte.MaxValue; Index++)
                    {
                        palette.Entries[Index] = Color.FromArgb(byte.MaxValue, Index, Index, Index);
                    }
                    bitmap.Palette = palette;
                    // bitmap.Save(@"C:\Users\15162\Desktop\bitmap.bmp");
                }
            }
            return bitmap;
        }
        private void stopGrabBtn_Click(object sender, EventArgs e)
        {
            startGrabFlag = false;
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            startGrabFlag = false;
            if (grabThread.IsAlive)
            {
                grabThread.Abort();
            }
            HOperatorSet.CloseFramegrabber(hv_AcqHandle);
            hv_AcqHandle.Dispose();
        }
    }
}

界面如下:
在这里插入图片描述
左边是Halcon的.Net 图形框插件 HWindowControl, 右边是PictureBox。
本Demo实现的效果是两个窗体实时实现同步的画面。
具体的转换方法请看上面代码。


http://www.niftyadmin.cn/n/1365144.html

相关文章

Inheritance: 'A' is an inaccessible base of 'B'

简介:B PRIVATE/protected 继承A&#xff0c;那么 A 的指针不能指向B 分析&#xff1a;private表示派生类是更加严格的基类或者在某方面继承了基类。 它不遵守 Liskov substitution principle。 $ cat inheritance.cpp #include <iostream>using namespace std;class A …

.NET C# 线程池

本文在这里会以一个Demo的案例介绍.NET C# 线程池开辟线程与普通模式下开辟线程的不同。 首先会对.NET C# 线程池一个大概的介绍&#xff1a; 直接给出书上的介绍吧。 这本书我是买的二手的&#xff0c;所以书上乱写的字体不是我画的&#xff0c;我对书做笔记是很干净的。 百…

稀疏矩阵-正交链表表示

//自己写出来的&#xff0c;测试过 #include<stdio.h> #include<stdlib.h> #define MaxSize 100 typedef enum { H, E } TagField; typedef struct term {int row, col, value; }Term; typedef struct mnode {struct mnode* Right, * Down;TagField Tag;union…

三元组表(顺序)表示下的稀疏矩阵的转置与相乘

#include<stdio.h> #include<stdlib.h> #define Compare(x,y) (((x)<(y))?-1:((x)(y)?0:1) typedef struct term {int row, col, value; }Term; typedef struct striples {int rows; int cols; int nonzeros;Term elem[31]; }Triples; Triples Trans(Tri…

文科生的悲哀(Vijos P1093)

心思散漫&#xff0c;看着题目就蛋疼&#xff0c;于是乎挑了一个软柿子捏。 刚开始真心没想到如此简单&#xff0c;虽然通过率很高。既然是模拟题&#xff0c;那就肯定要找规律&#xff0c;但是刚开始我倒是没有想到从每一层的科目个数上去寻找规律&#xff0c;而是想着把每门科…

一种C#读写二进制文件的通用方法

在日常的工作中&#xff0c;我们经常需要进行一些二进制文件或协议的读写操作&#xff0c;用C#解析二进制文件常常是一件比较麻烦且容易出错的工作&#xff0c;本文介绍了一种在C#中实现快速读写二进制文件通用的方法。 以一个解析Mp3 ID3V1标签头为例&#xff0c;ID3V1标签保存…

稀疏矩阵-加法运算-三元组表表示

//自己写的&#xff0c;亲测有效 #include<stdio.h> #include<stdlib.h> typedef struct term {int row; int col;int value; }Term;//一定要保证两个三元组表所代表的矩阵的行数和列数相等&#xff0c;即形状是一样的。 Term* Add2Triples(Term* elem1, int len1,…

如何做需求分析并根据需求进行设计,如何应对需求变化

系统开发的第一步为确定客户需求&#xff0c;只有开发出满足客户需求的系统才算是完成了工作&#xff0c;才算是有功劳。所以&#xff0c;不管因为什么原因&#xff0c;最后开发出的系统满足不了需求的话&#xff0c;开发人员的努力就变成了只有苦劳&#xff0c;没有功劳。需求…