using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using HalconDotNet;
using System.Net;
using MvCamCtrl.NET;
using System.Runtime.InteropServices;
//using FlyCapture2Managed;
namespace PointGreyAndHalcon
{
public delegate void GrabImageDoneDelegate(string recData, HImage recImage);
public class PointGreyAndHalcon
{
#region 定义
int camNum;
public HImage image = new HImage();
public event GrabImageDoneDelegate GrabImageDone;
public string SerialNo;
HImage tmpImage = new HImage();
bool isCameraOpen = false;
static MyCamera.MV_CC_DEVICE_INFO_LIST m_pDeviceList = new MyCamera.MV_CC_DEVICE_INFO_LIST();
readonly MyCamera device = new MyCamera();
MyCamera.MV_CC_DEVICE_INFO stDevInfo = new MyCamera.MV_CC_DEVICE_INFO();
int nRet = MyCamera.MV_OK;
#endregion
public PointGreyAndHalcon()
{
}
/////
///// 打开相机
/////
///// 编号
//public void OpenCamera(int index)
//{
// try
// {
// guid = busMgr.GetCameraFromIndex((uint)index);
// cam = new ManagedGigECamera();
// cam.Connect(guid);
// cam.StartCapture();
// isCameraOpen = true;
// }
// catch (Exception ex)
// {
// MessageBox.Show("相机" + index.ToString() + "打开失败");
// }
//}
///
/// 打开相机
///
/// IP地址
public bool OpenCamera(string ipAddress)
{
try
{
//将IP地址转换为字节数组
uint intAddress = 0;
if (!string.IsNullOrWhiteSpace(ipAddress))
{
byte[] IPArr = IPAddress.Parse(ipAddress).GetAddressBytes();
for (int i = 0; i < IPArr.Length; i++)
{
intAddress += (uint)(IPArr[i] << (IPArr.Length - 1 - i) * 8);
}
}
if (m_pDeviceList.pDeviceInfo == null)
{
int nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_pDeviceList);
if (0 != nRet)
{
throw new Exception($"Enumerate devices fail!");
}
}
bool isCameraFound = false;
for (int i = 0; i < m_pDeviceList.nDeviceNum; i++)
{
MyCamera.MV_CC_DEVICE_INFO device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));
IntPtr buffer = IntPtr.Zero;
buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0);
MyCamera.MV_GIGE_DEVICE_INFO stGigEDev = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
if (stGigEDev.nCurrentIp == intAddress)
{
stDevInfo = device;
isCameraFound = true;
}
if (isCameraFound)
break;
}
if (!isCameraFound)
{
throw new Exception($"相机{ipAddress}未能找到");
}
// ch:创建设备 | en: Create device
nRet = device.MV_CC_CreateDevice_NET(ref stDevInfo);
if (MyCamera.MV_OK != nRet)
{
throw new Exception($"Create device failed:{nRet:x8}");
}
// ch:打开设备 | en:Open device
nRet = device.MV_CC_OpenDevice_NET();
if (MyCamera.MV_OK != nRet)
{
throw new Exception($"Open device failed:{nRet:x8}");
}
// ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
int nPacketSize = device.MV_CC_GetOptimalPacketSize_NET();
if (nPacketSize > 0)
{
nRet = device.MV_CC_SetIntValue_NET("GevSCPSPacketSize", (uint)nPacketSize);
if (nRet != MyCamera.MV_OK)
{
Console.WriteLine("Warning: Set Packet Size failed {0:x8}", nRet);
}
}
else
{
Console.WriteLine("Warning: Get Packet Size failed {0:x8}", nPacketSize);
}
//// ch:注册回调函数 | en:Register image callback
//ImageCallback = new MyCamera.cbOutputExdelegate(ImageCallbackFunc);
//nRet = device.MV_CC_RegisterImageCallBackEx_NET(ImageCallback, IntPtr.Zero);
//if (MyCamera.MV_OK != nRet)
//{
// throw new Exception("Register image callback failed!");
//}
// ch:设置采集连续模式 | en:Set Continues Aquisition Mode
device.MV_CC_SetEnumValue_NET("AcquisitionMode", 2);// ch:工作在连续模式 | en:Acquisition On Continuous Mode
// ch:设置触发模式为On || en:set trigger mode as on
nRet = device.MV_CC_SetEnumValue_NET("TriggerMode", 1);
if (MyCamera.MV_OK != nRet)
{
throw new Exception("Set TriggerMode failed!");
}
//7 设置软件触发
nRet = device.MV_CC_SetEnumValue_NET("TriggerSource", (uint)7);
if (MyCamera.MV_OK != nRet)
{
throw new Exception($"Set Software Trigger failed!");
}
////设置取图缓存节点
//device.MV_CC_SetImageNodeNum_NET((uint)IIConfig.ImageNodeNum);
// ch:开启抓图 || en: start grab image
nRet = device.MV_CC_StartGrabbing_NET();
if (MyCamera.MV_OK != nRet)
{
throw new Exception($"Start grabbing failed:{nRet:x8}");
}
//取消自动曝光
device.MV_CC_SetEnumValue_NET("ExposureAuto", 0);
return true;
}
catch (Exception ex)
{
MessageBox.Show($"相机{ipAddress}打开失败\r\n{ex.Message}");
return false;
}
}
/////
///// 打开相机
/////
///// 序列号
//public void OpenCamera_test(uint serialnumber)
//{
// try
// {
// guid = busMgr.GetCameraFromSerialNumber(serialnumber);
// cam = new ManagedGigECamera();
// cam.Connect(guid);
// cam.StartCapture(Test);
// }
// catch (Exception ex)
// {
// MessageBox.Show("相机" + serialnumber.ToString() + "打开失败");
// }
//}
//private void Test(ManagedImage image)
//{
// lock (GetMutexLock())
// {
// SerialNo = "";
// try
// {
// //ManagedImage rawImage = new ManagedImage();
// // Retrieve an image
// //cam.RetrieveBuffer(rawImage);
// // Create a converted image
// ManagedImage convertedImage = new ManagedImage();
// // Convert the raw image
// image.Convert(FlyCapture2Managed.PixelFormat.PixelFormatMono8, convertedImage);
// //converterImage to HImage
// Bitmap tmpBmp = convertedImage.bitmap;
// BitmapData tmpBitmapData = tmpBmp.LockBits(new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height), ImageLockMode.ReadOnly,
// System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
// tmpImage.GenImage1("byte", tmpBmp.Width, tmpBmp.Height, tmpBitmapData.Scan0);
// if (GrabImageDone != null)
// {
// GrabImageDone("GrabSuccess", tmpImage);
// }
// tmpBmp.UnlockBits(tmpBitmapData);
// image.Dispose();
// convertedImage.Dispose();
// tmpBmp.Dispose();
// }
// catch (Exception ex)
// {
// if (GrabImageDone != null)
// {
// GrabImageDone("GrabFail", tmpImage);
// }
// }
// }
//}
///
/// 关闭相机
///
public void CloseCamera()
{
// ch:停止抓图 | en:Stop grab image
nRet = device.MV_CC_StopGrabbing_NET();
if (MyCamera.MV_OK != nRet)
{
throw new Exception($"Stop grabbing failed{nRet:x8}");
}
// ch:关闭设备 | en:Close device
nRet = device.MV_CC_CloseDevice_NET();
if (MyCamera.MV_OK != nRet)
{
throw new Exception($"Close device failed{nRet:x8}");
}
// ch:销毁设备 | en:Destroy device
nRet = device.MV_CC_DestroyDevice_NET();
if (MyCamera.MV_OK != nRet)
{
throw new Exception($"Destroy device failed:{nRet:x8}");
}
}
///
/// 采图
///
public void GrabImage(string sn)
{
lock (GetMutexLock())
{
SerialNo = sn;
try
{
nRet = device.MV_CC_SetCommandValue_NET("TriggerSoftware");
if (MyCamera.MV_OK != nRet)
{
throw new Exception($"相机拍照触发失败:{nRet}");
}
MyCamera.MV_FRAME_OUT frameInfo = new MyCamera.MV_FRAME_OUT();
nRet = device.MV_CC_GetImageBuffer_NET(ref frameInfo, 1000);
// ch:获取一帧图像 | en:Get one image
if (MyCamera.MV_OK == nRet)
{
int width = frameInfo.stFrameInfo.nWidth;
int height = frameInfo.stFrameInfo.nHeight;
if (frameInfo.pBufAddr != IntPtr.Zero)
{
HImage temp = new HImage();
temp.GenImage1("byte", width, height, frameInfo.pBufAddr);
tmpImage.Dispose();
tmpImage = null;
tmpImage = temp.CopyImage();
image.Dispose();
image = tmpImage.CopyImage();
if (GrabImageDone != null)
{
GrabImageDone("GrabSuccess", tmpImage);
}
nRet = device.MV_CC_FreeImageBuffer_NET(ref frameInfo);
if (nRet != MyCamera.MV_OK)
{
Console.WriteLine("Free Image Buffer fail:{0:x8}", nRet);
}
}
}
}
catch (Exception ex)
{
if (GrabImageDone != null)
{
GrabImageDone("GrabFail", tmpImage);
}
}
}
}
/////
///// 采彩色图
/////
//public void GrabColorImage(string sn)
//{
// SerialNo = sn;
// try
// {
// ManagedImage rawImage = new ManagedImage();
// // Retrieve an image
// cam.RetrieveBuffer(rawImage);
// // Create a converted image
// ManagedImage convertedImage = new ManagedImage();
// // Convert the raw image
// rawImage.Convert(FlyCapture2Managed.PixelFormat.PixelFormatBgr, convertedImage);
// //converterImage to HImage
// Bitmap tmpBmp = convertedImage.bitmap;
// Rectangle rect = new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height);
// BitmapData tmpBitmapData = tmpBmp.LockBits(rect, ImageLockMode.ReadOnly,
// System.Drawing.Imaging.PixelFormat.Format24bppRgb);
// #region 将RGB分离开来
// //创建新的彩色的bitmap
// Bitmap redBitmap = new Bitmap(tmpBmp.Width, tmpBmp.Height);
// Bitmap greenBitmap = new Bitmap(tmpBmp.Width, tmpBmp.Height);
// Bitmap blueBitmap = new Bitmap(tmpBmp.Width, tmpBmp.Height);
// //创建新的彩色的数据容器
// BitmapData redBmData = redBitmap.LockBits(rect, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
// BitmapData greenBmData = greenBitmap.LockBits(rect, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
// BitmapData blueBmData = blueBitmap.LockBits(rect, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
// //将Bitmap对象的信息存放到byte数组中
// int tmp_bytes = tmpBitmapData.Stride * tmpBmp.Height;
// int red_bytes = redBmData.Stride * tmpBmp.Height;
// int green_bytes = greenBmData.Stride * tmpBmp.Height;
// int blue_bytes = blueBmData.Stride * tmpBmp.Height;
// byte[] tmpValues = new byte[tmp_bytes];
// byte[] redValues = new byte[red_bytes];
// byte[] greenValues = new byte[green_bytes];
// byte[] blueValues = new byte[blue_bytes];
// //复制GRB信息到byte数组
// System.Runtime.InteropServices.Marshal.Copy(tmpBitmapData.Scan0, tmpValues, 0, tmp_bytes);
// System.Runtime.InteropServices.Marshal.Copy(redBmData.Scan0, redValues, 0, red_bytes);
// System.Runtime.InteropServices.Marshal.Copy(greenBmData.Scan0, greenValues, 0, green_bytes);
// System.Runtime.InteropServices.Marshal.Copy(blueBmData.Scan0, blueValues, 0, blue_bytes);
// //将彩色信息分别存储到RGB数组中
// for (int i = 0; i < tmpBmp.Height; i++)
// {
// for (int j = 0; j < tmpBmp.Width; j++)
// {
// int k = 3 * j;
// redValues[i * redBmData.Stride + j] = tmpValues[i * tmpBitmapData.Stride + k + 2];
// greenValues[i * blueBmData.Stride + j] = tmpValues[i * tmpBitmapData.Stride + k + 1];
// blueValues[i * greenBmData.Stride + j] = tmpValues[i * tmpBitmapData.Stride + k];
// }
// }
// //再将数组信息复制到RGB
// System.Runtime.InteropServices.Marshal.Copy(redValues, 0, redBmData.Scan0, red_bytes);
// System.Runtime.InteropServices.Marshal.Copy(greenValues, 0, greenBmData.Scan0, green_bytes);
// System.Runtime.InteropServices.Marshal.Copy(blueValues, 0, blueBmData.Scan0, blue_bytes);
// #endregion
// tmpImage.GenImage3("byte", tmpBmp.Width, tmpBmp.Height, redBmData.Scan0, greenBmData.Scan0, blueBmData.Scan0);
// if (GrabImageDone != null)
// {
// GrabImageDone("GrabSuccess", tmpImage);
// }
// tmpBmp.UnlockBits(tmpBitmapData);
// redBitmap.UnlockBits(redBmData);
// greenBitmap.UnlockBits(greenBmData);
// blueBitmap.UnlockBits(blueBmData);
// rawImage.Dispose();
// convertedImage.Dispose();
// tmpBmp.Dispose();
// redBitmap.Dispose();
// greenBitmap.Dispose();
// blueBitmap.Dispose();
// }
// catch (Exception ex)
// {
// if (GrabImageDone != null)
// {
// GrabImageDone("GrabFail", tmpImage);
// }
// }
//}
///
/// 将图片显示到图相框中
///
public void UpdateImage(HWindowControl viewPort)
{
HWndCtrl viewController = new HWndCtrl(viewPort);
ROIController roiController = new ROIController();
viewController.resetAll();
viewController.useROIController(roiController);
viewController.setViewState(HWndCtrl.MODE_VIEW_NONE);
viewController.addIconicVar(image);
viewController.repaint();
//image.Dispose();
}
///
/// 保存图片
///
///
///
public void SaveImage(string filePath, string fileName, string imgFormat)
{
image.WriteImage(imgFormat, 0, filePath + "\\" + fileName);
}
public void SetExposure(float exposure)
{
device.MV_CC_SetEnumValue_NET("ExposureAuto", 0);
nRet = device.MV_CC_SetFloatValue_NET("ExposureTime", exposure);
if (nRet != MyCamera.MV_OK)
{
throw new Exception($"Exposure set failed:{nRet}");
}
}
private static System.Threading.Mutex _mutex;
private System.Threading.Mutex GetMutexLock()
{
System.Threading.Interlocked.CompareExchange(ref _mutex, new System.Threading.Mutex(), null);
return _mutex;
}
}
}