相机可以在海康软件MVS中打开(颜色正常),但是在C#开发的程式中无法打开(彩色相机颜色显示异常)。
1.查看相机和MVS软件是否连接成功;
2.如果成功,连接C#程序;
3.程序连接失败,在MVS中连接相机,查看MVS里面相机的图像处理-像素格式,确定相机是否为黑白还是彩色相机,如下图:
由上图可知该相机为彩色相机。
4. 如果是彩色相机,但是颜色显示不对,根据彩色相机默认格式(可以将相机断电重新启动,再打开MVS软件连接查看默认图像格式),修改程序以下两个地方
Camera.MV_CC_SetEnumValueByString_NET("PixelFormat", "BayerRG8");
HOperatorSet.GenImage1(out image, "byte", frame.stFrameInfo.nWidth, frame.stFrameInfo.nHeight, frame.pBufAddr);
image = BayerToRgb(image, "bayer_rg");
image = RotateImage(image);
根据不同于颜色的排列,我们把Bayer分为BayerRG、BayerBG、BayerGB、BayerBG四种。
工业相机支持的图像格式种类,以海康工业相机为例子
连接相机封装类,以海康相机为例,程序要成功运行需要安装MVS软件,C#二次开发类,如下:
using HalconDotNet;
using MvCamCtrl.NET;
public class SvLucid
{
private MyCamera Camera;
public override void Initial()
{
try
{
base.Initial();
Camera = new MyCamera();
var infoList = new MyCamera.MV_CC_DEVICE_INFO_LIST();
MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE, ref infoList);
var result = -1;
for (int i = 0; i < infoList.nDeviceNum; i++)
{
var deviceInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(infoList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));
if (((MyCamera.MV_GIGE_DEVICE_INFO)MyCamera.ByteToStruct(deviceInfo.SpecialInfo.stGigEInfo, typeof(MyCamera.MV_GIGE_DEVICE_INFO))).chSerialNumber == SN)
{
Camera.MV_CC_CreateDevice_NET(ref deviceInfo);
result = Camera.MV_CC_OpenDevice_NET();
}
}
if (result != 0)
{
throw new Exception($"相機{SN}連接失敗");
}
result = 0;
if (Colorful == "黑白")
{
result += Camera.MV_CC_SetEnumValueByString_NET("PixelFormat", "Mono8");
}
else
{
result += Camera.MV_CC_SetEnumValueByString_NET("PixelFormat", "BayerRG8");
result += Camera.MV_CC_SetEnumValueByString_NET("BalanceWhiteAuto", "Off");
result += Camera.MV_CC_SetEnumValueByString_NET("BalanceRatioSelector", "Red");
result += Camera.MV_CC_SetFloatValue_NET("BalanceRatio", 2f);
result += Camera.MV_CC_SetEnumValueByString_NET("BalanceRatioSelector", "Green");
result += Camera.MV_CC_SetFloatValue_NET("BalanceRatio", 1f);
result += Camera.MV_CC_SetEnumValueByString_NET("BalanceRatioSelector", "Blue");
result += Camera.MV_CC_SetFloatValue_NET("BalanceRatio", 2f);
}
result += Camera.MV_CC_SetIntValue_NET("GevSCPSPacketSize", 9000);
result += Camera.MV_CC_SetIntValue_NET("GevSCPD", 80);
result += Camera.MV_CC_SetEnumValueByString_NET("TriggerSelector", "FrameStart");
result += Camera.MV_CC_SetEnumValueByString_NET("TriggerMode", "On");
result += Camera.MV_CC_SetEnumValueByString_NET("TriggerSource", "Software");
result += Camera.MV_CC_SetEnumValueByString_NET("TriggerActivation", "RisingEdge");
result += Camera.MV_CC_SetEnumValue_NET("ExposureAuto", 0);
result += Camera.MV_CC_SetEnumValue_NET("GainAuto", 0);
result += Camera.MV_CC_SetFloatValue_NET("ExposureTime", (float)Exposure);
result += Camera.MV_CC_SetFloatValue_NET("Gain", (float)Gain);
result += Camera.MV_CC_StartGrabbing_NET();
if (result != 0)
{
throw new Exception($"相機{SN}開啟失敗");
}
Thread.Sleep(500);
Snap();
}
catch (Exception ex)
{
SvMaster.Log.WriteError(ex);
}
}
public override void Close()
{
try
{
Camera.MV_CC_StopGrabbing_NET();
Camera.MV_CC_CloseDevice_NET();
Camera.MV_CC_DestroyDevice_NET();
}
catch (Exception ex)
{
SvMaster.Log.WriteError(ex);
}
}
public override void AdaptCamera()
{
try
{
Camera.MV_CC_SetFloatValue_NET("ExposureTime", (float)Exposure);
Camera.MV_CC_SetFloatValue_NET("Gain", (float)Gain);
}
catch (Exception ex)
{
SvMaster.Log.WriteError(ex);
}
}
public override HObject Snap()
{
HObject image = null;
var frame = new MyCamera.MV_FRAME_OUT();
try
{
Camera.MV_CC_SetCommandValue_NET("TriggerSoftware");
if (Camera.MV_CC_GetImageBuffer_NET(ref frame, 2000) == 0)
{
if (frame.stFrameInfo.nLostPacket > 0)
{
throw new Exception($"相機{SN}取像丢帧失敗");
}
HOperatorSet.GenImage1(out image, "byte", frame.stFrameInfo.nWidth, frame.stFrameInfo.nHeight, frame.pBufAddr);
image = BayerToRgb(image, "bayer_rg");
image = RotateImage(image);
}
else
{
throw new Exception($"相機{SN}取像失敗");
}
}
catch (Exception ex)
{
SvMaster.Log.WriteError(ex);
}
Camera.MV_CC_FreeImageBuffer_NET(ref frame);
return image;
}
}
说明: 引用MvCameraControl.Net.dll,在MVS安装目录下可以找到,可以在项目中引用。