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()
|
{
|
}
|
|
///// <summary>
|
///// 打开相机
|
///// </summary>
|
///// <param name="index">编号</param>
|
//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() + "打开失败");
|
|
// }
|
//}
|
|
/// <summary>
|
/// 打开相机
|
/// </summary>
|
/// <param name="serialnumber">IP地址</param>
|
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;
|
}
|
}
|
|
///// <summary>
|
///// 打开相机
|
///// </summary>
|
///// <param name="serialnumber">序列号</param>
|
//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);
|
// }
|
// }
|
// }
|
//}
|
|
/// <summary>
|
/// 关闭相机
|
/// </summary>
|
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}");
|
}
|
}
|
|
/// <summary>
|
/// 采图
|
/// </summary>
|
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);
|
}
|
}
|
}
|
}
|
|
///// <summary>
|
///// 采彩色图
|
///// </summary>
|
//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);
|
// }
|
// }
|
//}
|
|
/// <summary>
|
/// 将图片显示到图相框中
|
/// </summary>
|
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();
|
}
|
|
/// <summary>
|
/// 保存图片
|
/// </summary>
|
/// <param name="filePath"></param>
|
/// <param name="fileName"></param>
|
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;
|
}
|
}
|
}
|