在上一篇完成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实现的效果是两个窗体实时实现同步的画面。
具体的转换方法请看上面代码。