引入
代码
public class MVCamera : InterfaceCamera
{
#region 属性字段
PictureBox pb_ShowImage;//图像框
tSdkCameraDevInfo[] tCameraDevInfoList;
CameraSdkStatus status;
public static CameraHandle[] m_hCamera; // 句柄
CAMERA_SNAP_PROC m_CaptureCallback;
IntPtr m_iCaptureCallbackCtx; //图像回调函数的上下文参数
CAMERA_SNAP_PROC pCaptureCallOld = null;
IntPtr[] m_ImageBuffer; // 预览通道RGB图像缓存
tSdkCameraCapbility tCameraCapability; // 相机特性描述
HTuple hv_Width, hv_Height, hv_WindowHandle;
#endregion
#region 构造函数
public MVCamera()
{
}
public MVCamera(PictureBox pictureBox)
{
this.pb_ShowImage = pictureBox;
}
#endregion
/// <summary>
/// 关闭相机
/// </summary>
/// <param name="index"></param>
public void CloseCamera(int index)
{
}
/// <summary>
/// 查找相机
/// </summary>
/// <returns></returns>
public int EnumCamera()
{
//查找相机枚举设备
int Nums = 0;
status = MvApi.CameraEnumerateDevice(out tCameraDevInfoList);
if (tCameraDevInfoList?.Length > 0)
{
Nums = tCameraDevInfoList.Length;
m_hCamera = new CameraHandle[tCameraDevInfoList.Length];
m_ImageBuffer = new IntPtr[tCameraDevInfoList.Length];
}
if (status == CameraSdkStatus.CAMERA_STATUS_SUCCESS)
{
for (int i = 0; i < Nums; i++)
{
//2初始化相机+
status = MvApi.CameraInit(ref tCameraDevInfoList[i], -1, -1, ref m_hCamera[i]);
}
}
return Nums;
}
/// <summary>
/// 采集图像
/// </summary>
/// <param name="index"></param>
/// <param name="image"></param>
public void GrabImage(int index, out HObject image)
{
tSdkFrameHead pFrameHead;
IntPtr uRawBuffer;//rawbuffer由SDK内部申请。应用层不要调用delete之类的释放函数
HObject ho_BImageRGB2;
#region 转Halcon变量
//采集图像
MvApi.CameraGetImageBuffer(m_hCamera[index], out pFrameHead, out uRawBuffer, 500);
//图像处理,将原始输出转换为RGB格式的位图数据,同时叠加白平衡、饱和度、LUT等ISP处理。
MvApi.CameraImageProcess(m_hCamera[index], uRawBuffer, m_ImageBuffer[index], ref pFrameHead);
//图像变量转换两种方式第一种:gen_image_interleaved(多通道)
//HOperatorSet.GenImageInterleaved(out ho_BImageRGB2, m_ImageBuffer, "bgr", pFrameHead.iWidth,
//pFrameHead.iHeight, -1, "byte", pFrameHead.iWidth, pFrameHead.iHeight, 0, 0, -1, 0);
//第二种方式 gen_image3_extern gen_image1_extern
int bytesPerLineRGB = (pFrameHead.iWidth * 3 + 3) / 4 * 4;//24位彩色图像每行所在字节数
int bytesPerLineGray = (pFrameHead.iWidth + 3) / 4 * 4;//8位灰度图每行所在字节数
byte[] bufferRGB = new byte[bytesPerLineRGB * pFrameHead.iHeight];
byte[] bufferB = new byte[bytesPerLineGray * pFrameHead.iHeight];
byte[] bufferG = new byte[bytesPerLineGray * pFrameHead.iHeight];
byte[] bufferR = new byte[bytesPerLineGray * pFrameHead.iHeight];
byte[] bufferGray = new byte[bytesPerLineGray * pFrameHead.iHeight];
//将相机中采集的非托管内存数据 Copy到托管内存字节数组中
Marshal.Copy(m_ImageBuffer[index], bufferRGB, 0, bytesPerLineRGB * pFrameHead.iHeight);
for (int i = 0; i < pFrameHead.iHeight; i++)//如果是24位才这样拆
{
for (int j = 0; j < pFrameHead.iWidth; j++)
{
bufferB[i * bytesPerLineGray + j] = bufferRGB[i * bytesPerLineRGB + j * 3 + 0];//B分量
bufferG[i * bytesPerLineGray + j] = bufferRGB[i * bytesPerLineRGB + j * 3 + 1];//G分量
bufferR[i * bytesPerLineGray + j] = bufferRGB[i * bytesPerLineRGB + j * 3 + 2];//R分量
}
}
unsafe
{
fixed (byte* pr = bufferR, pg = bufferG, pb = bufferB)
{
HOperatorSet.GenImage3Extern(out ho_BImageRGB2, "byte", pFrameHead.iWidth, pFrameHead.iHeight, new IntPtr(pr), new IntPtr(pg), new IntPtr(pb), 0);
}
}
HOperatorSet.Rgb1ToGray(ho_BImageRGB2, out image);
if (index == 0)
{
HOperatorSet.RotateImage(image, out image, 90, "constant");
HOperatorSet.MirrorImage(image, out image, "row");
}
else
{
HOperatorSet.RotateImage(image, out image, 90, "constant");
HOperatorSet.MirrorImage(image, out image, "row");
}
MvApi.CameraReleaseImageBuffer(m_hCamera[index], uRawBuffer);
#endregion
}
/// <summary>
/// 打开相机
/// </summary>
/// <param name="index"></param>
public void OpenCamera(int index)
{
//获取当前相机设备信息
MvApi.CameraGetCapability(m_hCamera[index], out tCameraCapability);
//申请内存
m_ImageBuffer[index] = Marshal.AllocHGlobal(tCameraCapability.sResolutionRange.iWidthMax * tCameraCapability.sResolutionRange.iHeightMax * 3 + 1024);
//设置开始采集
MvApi.CameraPlay(m_hCamera[index]);
}
}