发现海康的sdk不错,可以用海康,basler,大华工业相机,估计其他的也可以,有机会试一试!国产厉害,崛起了!赞一个,热情爆棚!且随窃喜!
首先下载海康工业相机的安装包,并安装,安装后如图,打开:
他的开发包和范例安装包路径如下:
参考里边的可以写你想要的程序,当然是打开相机取像了,我使用的是他的bmp位图方式(你懂的,存图是z字序的),图像是反的,我给颠倒过来了:(这是黑白相机c#范例,后续还有彩色相机的)
第一,初始化:果断注释掉以前basler的,只留海康
#region haikangcam
// ch:枚举设备 | en:Enum device
if (nDevIndex == -1) { MessageBox.Show("请选择相机"); return; }
MyCamera.MV_CC_DEVICE_INFO_LIST stDevList = new MyCamera.MV_CC_DEVICE_INFO_LIST();
nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE, ref stDevList);//| MyCamera.MV_USB_DEVICE
MyCamera.MV_CC_DEVICE_INFO stDevInfo;
for (Int32 i = 0; i < stDevList.nDeviceNum; i++)
{
stDevInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(stDevList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));
if (MyCamera.MV_GIGE_DEVICE == stDevInfo.nTLayerType)
{
MyCamera.MV_GIGE_DEVICE_INFO stGigEDeviceInfo = (MyCamera.MV_GIGE_DEVICE_INFO)MyCamera.ByteToStruct(stDevInfo.SpecialInfo.stGigEInfo, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
string str= stGigEDeviceInfo.chModelName;
bool youwu00 = str.Contains("gc");//彩色判断
bool youwu01 = str.Contains("gC");
bool youwu10 = str.Contains("Gc");
bool youwu11 = str.Contains("GC");
if (youwu00 || youwu01 || youwu10 || youwu11) { checkBoxBW.Checked = false; } else { checkBoxBW.Checked = true; }
}
stDevInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(stDevList.pDeviceInfo[nDevIndex], typeof(MyCamera.MV_CC_DEVICE_INFO));
// ch:创建设备 | en:Create device
nRet = device.MV_CC_CreateDevice_NET(ref stDevInfo);
// ch:打开设备 | en:Open device
nRet = device.MV_CC_OpenDevice_NET();
// ch:设置触发模式为off || en:set trigger mode as off
if (MyCamera.MV_OK != device.MV_CC_SetEnumValue_NET("TriggerMode", 0))
{
//控制台的,没用,删掉
}
device.MV_CC_SetEnumValue_NET("ExposureAuto", 0);
float value = (float)(Convert.ToDouble(textBox3.Text));//改为880000
int hello = device.MV_CC_SetExposureTime_NET(value);//感觉有效果202208060942
// ch:开启抓图 | en:start grab
nRet = device.MV_CC_StartGrabbing_NET();
if (MyCamera.MV_OK != nRet)
{
}
// ch:获取包大小 || en: Get Payload Size
MyCamera.MVCC_INTVALUE stParam = new MyCamera.MVCC_INTVALUE();
nRet = device.MV_CC_GetIntValue_NET("PayloadSize", ref stParam);
if (MyCamera.MV_OK != nRet)
{
}
nPayloadSize = stParam.nCurValue;
pBufForDriver = Marshal.AllocHGlobal((int)nPayloadSize);
}
#endregion haikangcam
第二,上面第一句执行不了,返回了,所以问题在这里:
a,引用,using MvCamCtrl.NET;
b,声明变量, //ishaikang20211230
MyCamera device = new MyCamera();
int nRet = MyCamera.MV_OK;
MyCamera.MVCC_INTVALUE stParam;
UInt32 nPayloadSize;
// int nCount = 0;
IntPtr pBufForDriver;
IntPtr pBufForSaveImage = IntPtr.Zero;
MyCamera.MV_FRAME_OUT_INFO_EX FrameInfo = new MyCamera.MV_FRAME_OUT_INFO_EX();
c,枚举相机,添加到combox:
//列举相机个数
// int nRet = MyCamera.MV_OK;
// MyCamera device = new MyCamera();
// ch:枚举设备 | en:Enum device
MyCamera.MV_CC_DEVICE_INFO_LIST stDevList1 = new MyCamera.MV_CC_DEVICE_INFO_LIST();
do
{
int tempint = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref stDevList1);
if (MyCamera.MV_OK != tempint)
{
break;
}
textBoxcamno.Text = stDevList1.nDeviceNum.ToString();
if (0 == stDevList1.nDeviceNum)
{
break;
}
} while (false);
MyCamera.MV_CC_DEVICE_INFO stDevInfo;
for (Int32 i = 0; i < stDevList1.nDeviceNum; i++)
{
stDevInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(stDevList1.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));
if (MyCamera.MV_GIGE_DEVICE == stDevInfo.nTLayerType)
{
MyCamera.MV_GIGE_DEVICE_INFO stGigEDeviceInfo = (MyCamera.MV_GIGE_DEVICE_INFO)MyCamera.ByteToStruct(stDevInfo.SpecialInfo.stGigEInfo, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
comboBoxCamSel.Items.Add(i.ToString());// + //":" + stGigEDeviceInfo.chSerialNumber +":"+ stGigEDeviceInfo.chModelName.ToString()+
//"\r\n";
}
}
第三,万事具备,取像,连续取像,开一个timer,启动:
int ww = Convert.ToInt32(inputW.Text);//无论是2千万,还是200万,我只去1024*768
int hh = Convert.ToInt32(inputH.Text);//无论是2千万,还是200万,我只去1024*768
nRet = device.MV_CC_GetOneFrameTimeout_NET(pBufForDriver, nPayloadSize, ref FrameInfo, 1000);
第四,ok,完了,但要显示出来,并且把数据放入二维数组,需要花费功夫(这里先处理黑白相机,默认8位):
if (pBufForSaveImage == IntPtr.Zero)
{
pBufForSaveImage = Marshal.AllocHGlobal((int)(FrameInfo.nHeight * FrameInfo.nWidth * 3 + 2048));
}
MyCamera.MV_SAVE_IMAGE_PARAM_EX stSaveParam = new MyCamera.MV_SAVE_IMAGE_PARAM_EX();
stSaveParam.enImageType = MyCamera.MV_SAVE_IAMGE_TYPE.MV_Image_Bmp;
stSaveParam.enPixelType = FrameInfo.enPixelType;
stSaveParam.pData = pBufForDriver;
stSaveParam.nDataLen = FrameInfo.nFrameLen;
stSaveParam.nHeight = FrameInfo.nHeight;
stSaveParam.nWidth = FrameInfo.nWidth;
stSaveParam.pImageBuffer = pBufForSaveImage;
stSaveParam.nBufferSize = (uint)(FrameInfo.nHeight * FrameInfo.nWidth * 3 + 2048);
stSaveParam.nJpgQuality = 80;
nRet = device.MV_CC_SaveImageEx_NET(ref stSaveParam);
byte[] data = new byte[stSaveParam.nImageLen];
Marshal.Copy(pBufForSaveImage, data, 0, (int)stSaveParam.nImageLen);
//以下是针对黑白相机的//这个黑白相机程序也是ok的,但与彩色相机程序有差别//20220427
byte[] tempdata2 = new byte[FrameInfo.nHeight * FrameInfo.nWidth];
for (int i = 0 + 1078; i < FrameInfo.nHeight * FrameInfo.nWidth + 1078; i++)
{
tempdata2[i - 1078] = data[i];
}
byte[] data2 = new byte[FrameInfo.nHeight * FrameInfo.nWidth];
for(int i=0;i
data2[i *FrameInfo.nWidth + j] = tempdata2[(FrameInfo.nHeight - 1 - i) * FrameInfo.nWidth + j];
}
int bytes = ww * hh * 3;
byte[] bufercopy = new byte[bytes];
Bitmap cutPic24 = new Bitmap(ww, hh,
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
BitmapData _cutPic = cutPic24.LockBits(new Rectangle(0, 0, ww, hh),
ImageLockMode.ReadWrite, cutPic24.PixelFormat);
IntPtr ptr = _cutPic.Scan0;//得到首地址
int yy = (FrameInfo.nHeight - hh) / 2;//FrameInfo.nHeight
int xx = (FrameInfo.nWidth - ww) / 2;// FrameInfo.nWidth
for (int ii = yy; ii < yy + hh; ii++)//图像复原,即由8位图变成24位图像
{
for (int j = xx; j < xx + ww; j++)
{//位图z序颠倒后,正常
int n = ii * FrameInfo.nWidth + j;
int k = (ii - yy) * ww + j - xx;
int m = 3 * k;
glob_buffer8[k] = checkBoxConvertBW.Checked ? (byte)(255 - data2[n]) : data2[n];//为什么可以,可以验证,可以分析202209231111
bufercopy[m] = data2[n];
bufercopy[m + 1] = data2[n];
bufercopy[m + 2] = data2[n];
}
}
showbuffer2pict(data2, FrameInfo.nWidth, FrameInfo.nHeight, pictureBoxrgb);
第五,解释showbuffer2pict函数:(主要针对黑白8为图像显示)
void showbuffer2pict(byte[] buffer, int ww, int hh,PictureBox destImg)
{
// destImg.Size = new System.Drawing.Size(ww, hh);
//顯示
byte[] cutvalues = new byte[ww * hh * 3];
int bytes = ww * hh * 3;
Bitmap cutPic24 = new Bitmap(ww, hh, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
BitmapData _cutPic = cutPic24.LockBits(new Rectangle(0, 0, ww, hh), ImageLockMode.ReadWrite,
cutPic24.PixelFormat);
IntPtr ptr = _cutPic.Scan0;//得到首地址
for (int i = 0; i < hh; i++)
{
for (int j = 0; j < ww; j++)
{
int n = i * ww + j;
int m = 3 * n;
cutvalues[m] = buffer[n];
cutvalues[m + 1] = buffer[n];
cutvalues[m + 2] = buffer[n];
}
}
System.Runtime.InteropServices.Marshal.Copy(cutvalues, 0, ptr, bytes);
cutPic24.UnlockBits(_cutPic);
destImg.Image = cutPic24;
}