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; } } }