Bitmap Hobject Mat BinaryBitmap ImageBaseData_V2格式图像互相转换
#region Bitmap Hobject Mat格式图像互相转换
/// <summary>
/// 把source指针长度为size的数据复制到指针dest
/// </summary>
/// <param name="dest">要复制到的地址</param>
/// <param name="source">复制源的地址</param>
/// <param name="size">复制的长度</param>
/// <returns></returns>
[DllImport("kernel32.dll")]
public extern static long CopyMemory(IntPtr dest, IntPtr source, int size);
/// <summary>
/// 把Halcon图像转换到OpenCV图像
/// </summary>
/// <param name="hImage">Halcon图像_HObject</param>
/// <returns>OpenCV图像_Mat</returns>
public Mat HImageToMat(HObject hImage)
{
try
{
Mat mImage; // 返回值
HTuple htChannels; // 通道
HTuple cType = null; // 类型
HTuple width, height; // 宽,高
width = height = 0;
htChannels = null;
HOperatorSet.CountChannels(hImage, out htChannels); // 获取通道
// 通道存在值
if (htChannels.Length == 0)
{
return null;
}
if (htChannels[0].I == 1) // 单通道
{
HTuple ptr; // HTuple_单通道值指针
HOperatorSet.GetImagePointer1(hImage, out ptr, out cType, out width, out height); // 单通道取值方法(图片,输出“单通道值指针”,输出“类型”,输出“宽”,输出“高”) // (ptr=2157902018096 cType=byte width=830 height=822)
mImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1, new Scalar(0)); // 实例化mImage(大小,MatType.CV_8UC1,new Scalar(0))
int Width = width;
unsafe
{
//for (int i = 0; i < height; i++) // 循环赋值
//{
// IntPtr start = IntPtr.Add(mImage.Data, i * width); // Mat的单通道_Data地址+偏移(start=0x000001f66d4df300 Data=0x000001f66d4df300 i * 830)
// CopyMemory(start, new IntPtr((byte*)ptr.IP + width * i), width); // CopyMemory(要复制到的地址,复制源的地址,复制的长度)
//}
CopyMemory(mImage.Data, new IntPtr((byte*) ptr.IP), width* height);// CopyMemory(复制到的地址,复制源的地址,复制的长度)
}
return mImage;
}
else if (htChannels[0].I == 3) // 三通道
{
HTuple ptrRed; // HTuple_R通道值指针
HTuple ptrGreen; // HTuple_G通道值指针
HTuple ptrBlue; // HTuple_B通道值指针
HOperatorSet.GetImagePointer3(hImage, out ptrRed, out ptrGreen, out ptrBlue, out cType,out width, out height); // 三通道取值方法(图片,输出“R通道值指针”,输出“G通道值指针”,输出“B通道值针”,输出“型”,输出“宽”,输出“高”)
Mat pImageRed = new Mat(new OpenCvSharp.Size(width,height),MatType.CV_8UC1); // Mat_R通道值指针(大小,MatType.CV_8UC1)
Mat pImageGreen = new Mat(new OpenCvSharp.Size(width,height),MatType.CV_8UC1); // Mat_G通道值指针(大小,MatType.CV_8UC1)
Mat pImageBlue = new Mat(new OpenCvSharp.Size(width,height),MatType.CV_8UC1); // Mat_B通道值指针(大小,MatType.CV_8UC1)
mImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC3, new Scalar(0, 0, 0)); // Mat_图片(大小,MatType.CV_8UC1,new Scalar(0, 0, 0))
unsafe
{
//for (int i = 0; i < height; i++)
//{
// //long step = mImage.Step();
// IntPtr startRed = IntPtr.Add(pImageRed.Data, i * width); /Mat的Red_Data地址+偏移(start=0x000001f66d4df300 Data=0x000001f66d4df300 i * 830)
// IntPtr startGreen = IntPtr.Add(pImageGreen.Data, i * width); /Mat的Green_Data地址+偏移(start=0x000001f66d4df300 Data=0x000001f66d4df300 i * 830)
// IntPtr startBlue = IntPtr.Add(pImageBlue.Data, i * width); /Mat的Blue_Data地址+偏移(start=0x000001f66d4df300 Data=0x000001f66d4df300 i * 830)
// CopyMemory(startRed, new IntPtr((byte*)ptrRed.IP + width * i), width); /CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Red
// CopyMemory(startGreen, new IntPtr((byte*)ptrGreen.IP + width * i), width); /CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Green
// CopyMemory(startBlue, new IntPtr((byte*)ptrBlue.IP + width * i), width); /CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Blue
//}
CopyMemory(pImageRed.Data, new IntPtr((byte*)ptrRed.IP), width * height); // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Red
CopyMemory(pImageGreen.Data, new IntPtr((byte*)ptrGreen.IP), width*height); // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Green
CopyMemory(pImageBlue.Data, new IntPtr((byte*)ptrBlue.IP), width*height); // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Blue
}
Mat[] multi = new Mat[] { pImageBlue, pImageGreen, pImageRed }; // 存储rgb三通道
Cv2.Merge(multi, mImage); // rgb三通道合成一图
pImageRed.Dispose(); // Mat_R通道值指针毁
pImageGreen.Dispose(); // Mat_G通道值指针毁
pImageBlue.Dispose(); // Mat_B通道值指针毁
return mImage;
}
else
{
return null;
}
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 把OpenCV图像转换到Halcon图像
/// </summary>
/// <param name="mImage">OpenCV图像_Mat</param>
/// <returns>Halcon图像_HObject</returns>
public HObject MatToHImage(Mat mImage)
{
try
{
HObject hImage;
int matChannels = 0; // 通道数
Type matType = null;
int width, height; // 宽,高
width = height = 0; // 宽,高初始化
// 获取通道数
matChannels = mImage.Channels();
if (matChannels == 0)
{
return null;
}
if (matChannels == 1) // 单通道
{
IntPtr ptr; // 灰度图通道
Mat[] mats = mImage.Split();
// 改自:Mat.GetImagePointer1(mImage, out ptr, out matType, out width, out height); // ptr=2157902018096 cType=byte width=830 height=822
ptr = mats[0].Data; // 取灰度图值
matType = mImage.GetType(); // byte
height = mImage.Rows; // 高
width = mImage.Cols; // 宽
// 改自:hImage = new HObject(new OpenCvSharp.Size(width, height), MatType.CV_8UC1, newScalar(0));
byte[] dataGrayScaleImage = new byte[width * height]; //Mat dataGrayScaleImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
unsafe
{
fixed (byte* ptrdata = dataGrayScaleImage)
{
#region 按行复制
//for (int i = 0; i < height; i++)
//{
// CopyMemory((IntPtr)(ptrdata + width * i), new IntPtr((long)ptr + width *i), width);
//}
#endregion
CopyMemory((IntPtr)ptrdata, new IntPtr((long)ptr), width * height);
HOperatorSet.GenImage1(out hImage, "byte", width, height, (IntPtr) ptrdata);
}
}
return hImage;
}
else if (matChannels == 3) // 三通道
{
IntPtr ptrRed; // R通道图
IntPtr ptrGreen; // G通道图
IntPtr ptrBlue; // B通道图
Mat[] mats = mImage.Split();
ptrRed = mats[0].Data; // 取R通道值
ptrGreen = mats[1].Data; // 取G通道值
ptrBlue = mats[2].Data; // 取B通道值
matType = mImage.GetType(); // 类型
height = mImage.Rows; // 高
width = mImage.Cols; // 宽
// 改自:hImage = new HObject(new OpenCvSharp.Size(width, height), MatType.CV_8UC1, new Scalar(0));
byte[] dataRed = new byte[width * height]; //Mat dataGrayScaleImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
byte[] dataGreen = new byte[width * height];
byte[] dataBlue = new byte[width * height];
unsafe
{
fixed (byte* ptrdataRed = dataRed, ptrdataGreen = dataGreen, ptrdataBlue = dataBlue)
{
#region 按行复制
//HImage himg = new HImage("byte", width, height, (IntPtr)ptrdataRed);
//for (int i = 0; i < height; i++)
//{
// CopyMemory((IntPtr)(ptrdataRed + width * i), new IntPtr((long)ptrRed +width * i), width);
// CopyMemory((IntPtr)(ptrdataGreen + width * i), new IntPtr((long)ptrGreen+ width * i), width);
// CopyMemory((IntPtr)(ptrdataBlue + width * i), new IntPtr((long)ptrBlue +width * i), width);
//}
#endregion
CopyMemory((IntPtr)ptrdataRed, new IntPtr((long)ptrRed), width *height); // 复制R通道
CopyMemory((IntPtr)ptrdataGreen, new IntPtr((long)ptrGreen), width *height); // 复制G通道
CopyMemory((IntPtr)ptrdataBlue, new IntPtr((long)ptrBlue), width *height); // 复制B通道
HOperatorSet.GenImage3(out hImage, "byte", width, height, (IntPtr)ptrdataRed, (IntPtr)ptrdataGreen, (IntPtr)ptrdataBlue); // 合成
}
}
return hImage;
}
else
{
return null;
}
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 彩色Bitmap转彩色Hobject
/// </summary>
/// <param name="bmp"></param>
/// <param name="image"></param>
public void Bitmap2HObjectBpp24(Bitmap bmp, out HObject image)
{
try
{
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
HOperatorSet.GenImageInterleaved(out image, srcBmpData.Scan0, "bgr", bmp.Width, bmp.Height, 0, "byte", 0, 0, 0, 0, -1, 0);
bmp.UnlockBits(srcBmpData);
}
catch
{
image = null;
}
}
/// <summary>
/// 8位灰度Bitmap转Hobject
/// </summary>
/// <param name="bmp"></param>
/// <param name="image"></param>
public void Bitmap2HObjectBpp8(Bitmap bmp, out HObject image)
{
try
{
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
HOperatorSet.GenImage1(out image, "byte", bmp.Width, bmp.Height, srcBmpData.Scan0);
bmp.UnlockBits(srcBmpData);
}
catch
{
image = null;
}
}
/// <summary>
/// 彩色Hobject转Bitmap
/// </summary>
/// <param name="ho_image"></param>
/// <param name="res24"></param>
public void HObject2Bpp24(HObject ho_image, out Bitmap res24)
{
HTuple width0, height0, type, width, height;
//获取图像尺寸
HOperatorSet.GetImageSize(ho_image, out width0, out height0);
//创建交错格式图像
HOperatorSet.InterleaveChannels(ho_image, out HObject InterImage, "argb", "match", 255); //"rgb", 4 * width0, 0 "argb", "match", 255
//获取交错格式图像指针
HOperatorSet.GetImagePointer1(InterImage, out HTuple Pointer, out type, out width, out height);
IntPtr ptr = Pointer;
//构建新Bitmap图像
Bitmap res32 = new Bitmap(width / 4, height, width, PixelFormat.Format32bppArgb, ptr); // Format32bppArgb Format24bppRgb
//32位Bitmap转24位
res24 = new Bitmap(res32.Width, res32.Height, PixelFormat.Format24bppRgb);
Graphics graphics = Graphics.FromImage(res24);
graphics.DrawImage(res32, new Rectangle(0, 0, res32.Width, res32.Height));
res32.Dispose();
}
/// <summary>
/// 8位灰度Hobject转Bitmap
/// </summary>
/// <param name="image"></param>
/// <param name="res"></param>
public void HObject2Bpp8_(HObject image, out Bitmap res)
{
HTuple hpoint, type, width, height;
const int Alpha = 255;
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;
IntPtr ptr1 = bitmapData.Scan0;
IntPtr ptr2 = hpoint;
int bytes = width * height;
byte[] rgbvalues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr2, rgbvalues, 0, bytes);
System.Runtime.InteropServices.Marshal.Copy(rgbvalues, 0, ptr1, bytes);
res.UnlockBits(bitmapData);
}
/// <summary>
/// Mat转bitmap
/// </summary>
/// <param name="mat"></param>
/// <param name="res"></param>
public void Mat2Bitmap(Mat mat,out Bitmap res)
{
if (mat != null)
{
res = BitmapConverter.ToBitmap(mat);
}
else
{
res = null;
}
}
/// <summary>
/// Bitmap转Mat
/// </summary>
/// <param name="bmp"></param>
/// <param name="res"></param>
public void Bitmap2Mat(Bitmap bmp, out Mat res)
{
if (bmp != null)
{
res = BitmapConverter.ToMat(bmp);
}
else
{
res = null;
}
}
/// <summary>
/// Bitmap ConvertTo BinaryBitmap
/// </summary>
/// <param name="bitmap">位图</param>
/// <param name="binarybitmap">ZXing的二进制位图</param>
public void Bitmap2BinaryBitmap(Bitmap bitmap,out BinaryBitmap binarybitmap)
{
BinaryBitmap bbmp;
try
{
if (bitmap != null)
{
LuminanceSource source = new BitmapLuminanceSource(bitmap);
var binarizer = new GlobalHistogramBinarizer(source);
bbmp = new BinaryBitmap(binarizer);
binarybitmap = bbmp;
}
else
{
binarybitmap = null;
}
}
catch
{
binarybitmap = null;
}
}
/// <summary>
/// ZXing.BinaryBitmap ConvertTo Bitmap
/// </summary>
/// <param name="binarybitmap">ZXing.BinaryBitmap</param>
/// <param name="bitmap">位图</param>
public void BinaryBitmap2Bitmap(BinaryBitmap binarybitmap,out Bitmap bitmap)
{
try
{
if (binarybitmap != null)
{
BitMatrix bitmatrix = binarybitmap.BlackMatrix;
bitmap = new Bitmap(bitmatrix.Width, bitmatrix.Height);
for (int i = 0; i < bitmatrix.Width; i++)
{
for (int j = 0; j < bitmatrix.Height; j++)
{
bitmap.SetPixel(i, j, bitmatrix[i, j] ? Color.Black : Color.White);
}
}
}
else
{
bitmap = null;
}
}
catch
{
bitmap = null;
}
}
/// <summary>
///ICogImage转为Hobject、ImageBaseData_V2
/// </summary>
/// <param name="sourceimage">原始图像</param>
public static T ICogImage2VMImageOrHobject<T>(ICogImage sourceimage)
{
Type t = typeof(T);
if (t==typeof(ImageBaseData_V2))
{
ImageBaseData_V2 imagebasedata_v2 = null;
if (typeof(CogImage24PlanarColor)==sourceimage.GetType()) //彩色图像
{
Bitmap bmp = sourceimage.ToBitmap();
PixelFormat bitPixelFormat = bmp.PixelFormat;
BitmapData bmpData = bmp.LockBits(new Rectangle(0,0,bmp.Width,bmp.Height),ImageLockMode.ReadWrite,bitPixelFormat);
if (bitPixelFormat ==PixelFormat.Format24bppRgb)
{
uint ImagebaseDataSize = (uint)(bmpData.Width * bmpData.Height * 3);
imagebasedata_v2 = new ImageBaseData_V2(bmpData.Scan0,ImagebaseDataSize,bmpData.Width,bmpData.Height,VMPixelFormat.VM_PIXEL_RGB24_C3);
}
}
else if (typeof(CogImage8Grey)==sourceimage.GetType()) //灰度图像
{
IntPtr pointer = (sourceimage as CogImage8Grey).Get8GreyPixelMemory(CogImageDataModeConstants.Read, 0, 0, (sourceimage as CogImage8Grey).Width, (sourceimage as CogImage8Grey).Height).Scan0;
uint datalen = (uint)((sourceimage as CogImage8Grey).Width * (sourceimage as CogImage8Grey).Height);
imagebasedata_v2 = new ImageBaseData_V2(pointer, datalen, (sourceimage as CogImage8Grey).Width, (sourceimage as CogImage8Grey).Height, VMPixelFormat.VM_PIXEL_MONO_08);
}
return (T)(object)imagebasedata_v2;
}
else if (t == typeof(HObject))
{
HObject ho_image = new HObject();
if (typeof(CogImage24PlanarColor) == sourceimage.GetType()) //彩色图像
{
(sourceimage as CogImage24PlanarColor).Get24PlanarColorPixelMemory(CogImageDataModeConstants.Read, 0, 0, sourceimage.Width, sourceimage.Height, out ICogImage8PixelMemory m1, out ICogImage8PixelMemory m2, out ICogImage8PixelMemory m3);
HOperatorSet.GenImage3(out ho_image,"byte",sourceimage.Width,sourceimage.Height,m1.Scan0,m2.Scan0,m3.Scan0);
}
else if (typeof(CogImage8Grey) == sourceimage.GetType()) //灰度图像
{
IntPtr Pointer = (sourceimage as CogImage8Grey).Get8GreyPixelMemory(CogImageDataModeConstants.Read,0,0,sourceimage.Width,sourceimage.Height).Scan0;
HOperatorSet.GenImage1(out ho_image,"byte",sourceimage.Width,sourceimage.Height,Pointer);
}
return (T)(object)ho_image;
}
return default(T);
}
#endregion