<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
最近做專案需要對海康相機進行二次開發,現將所學進行整理。
開發環境 VS2012+C#(32位元) Halcon12
參照Halcon動態連結庫(halcondotnet.dll)
參照海康相機動態連結庫(MvCameraControl.Net.dll)這個檔案在MVS安裝目錄下MVSDevelopmentDotNet中,如果你是32位元的開發環境就選擇win32資料夾下的,如果是64位元就選擇win64資料夾下的
先在建立的類中編寫方法,之後範例化相機類,呼叫類中的方法。
滑鼠右鍵單擊工程專案–新增–類,選擇“類”,輸入類的名稱,例如Hikvision,點選右下角的“新增”。
首先,要引入的名稱空間:using HalconDotNet; using MvCamCtrl.NET;
其次,需要用到的全部變數:
private MyCamera m_pMyCamera; MyCamera.MV_CC_DEVICE_INFO_LIST m_pDeviceList;//裝置列表 private MyCamera.MVCC_INTVALUE stParam;//用於接收特定的引數 //為讀取、儲存影象建立的陣列 UInt32 m_nBufSizeForDriver = 3072 * 2048 * 3; byte[] m_pBufForDriver = new byte[3072 * 2048 * 3]; UInt32 m_nBufSizeForSaveImage = 3072 * 2048 * 3 * 3 + 2048; byte[] m_pBufForSaveImage = new byte[3072 * 2048 * 3 * 3 + 2048]; //要轉成的Halcon影象 HImage image = new HImage();
//查詢裝置 public void DeviceListAcq() { int nRet; // ch:建立裝置列表 en:Create Device List System.GC.Collect(); cbDeviceList.Items.Clear(); nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_pDeviceList); if (0 != nRet) { MessageBox.Show("查詢裝置失敗!"); return; } // ch:在表單列表中顯示裝置名 | en:Display device name in the form list 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)); if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE) { IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0); MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO)); if (gigeInfo.chUserDefinedName != "") { cbDeviceList.Items.Add("GigE: " + gigeInfo.chUserDefinedName + " (" + gigeInfo.chSerialNumber + ")"); } else { cbDeviceList.Items.Add("GigE: " + gigeInfo.chManufacturerName + " " + gigeInfo.chModelName + " (" + gigeInfo.chSerialNumber + ")"); } } else if (device.nTLayerType == MyCamera.MV_USB_DEVICE) { IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stUsb3VInfo, 0); MyCamera.MV_USB3_DEVICE_INFO usbInfo = (MyCamera.MV_USB3_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_USB3_DEVICE_INFO)); if (usbInfo.chUserDefinedName != "") { cbDeviceList.Items.Add("USB: " + usbInfo.chUserDefinedName + " (" + usbInfo.chSerialNumber + ")"); } else { cbDeviceList.Items.Add("USB: " + usbInfo.chManufacturerName + " " + usbInfo.chModelName + " (" + usbInfo.chSerialNumber + ")"); } } } // ch:選擇第一項 | en:Select the first item if (m_pDeviceList.nDeviceNum != 0) { cbDeviceList.SelectedIndex = 0; } }
//開啟裝置 public void OpenDevice() { if (m_pDeviceList.nDeviceNum == 0 || cbDeviceList.SelectedIndex == -1) { MessageBox.Show("未發現裝置,請選擇"); return; } int nRet = -1; // ch:獲取選擇的裝置資訊 | en:Get selected device information MyCamera.MV_CC_DEVICE_INFO device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[cbDeviceList.SelectedIndex], typeof(MyCamera.MV_CC_DEVICE_INFO)); // ch:開啟裝置 | en:Open device if (null == m_pMyCamera) { m_pMyCamera = new MyCamera(); if (null == m_pMyCamera) { return; } } nRet = m_pMyCamera.MV_CC_CreateDevice_NET(ref device); if (MyCamera.MV_OK != nRet) { return; } nRet = m_pMyCamera.MV_CC_OpenDevice_NET(); if (MyCamera.MV_OK != nRet) { m_pMyCamera.MV_CC_DestroyDevice_NET(); MessageBox.Show("裝置開啟失敗"); //ShowErrorMsg("Device open fail!", nRet); return; } // ch:探測網路最佳包大小(只對GigE相機有效) | en:Detection network optimal package size(It only works for the GigE camera) if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE) { int nPacketSize = m_pMyCamera.MV_CC_GetOptimalPacketSize_NET(); if (nPacketSize > 0) { nRet = m_pMyCamera.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:Set Continues Aquisition Mode m_pMyCamera.MV_CC_SetEnumValue_NET("AcquisitionMode", 2);// ch:工作在連續模式 | en:Acquisition On Continuous Mode m_pMyCamera.MV_CC_SetEnumValue_NET("TriggerMode", 0); // ch:連續模式 | en:Continuous }
//連續採集(也就是實時顯示) public void ContinuesGrab(PictureBox picBox) { int nRet; // ch:開始採集 | en:Start Grabbing nRet = m_pMyCamera.MV_CC_StartGrabbing_NET(); if (MyCamera.MV_OK != nRet) { MessageBox.Show("採集失敗!"); //ShowErrorMsg("Trigger Fail!", nRet); return; } //實時採集 m_pMyCamera.MV_CC_SetEnumValue_NET("TriggerMode", 0); // ch:顯示 | en:Display 在PictureBox控制元件中顯示 nRet = m_pMyCamera.MV_CC_Display_NET(picBox.Handle); if (MyCamera.MV_OK != nRet) { MessageBox.Show("顯示失敗!"); } }
//停止採集 public void StopGrab() { int nRet = -1; // ch:停止採集 | en:Stop Grabbing nRet = m_pMyCamera.MV_CC_StopGrabbing_NET(); if (nRet != MyCamera.MV_OK) { MessageBox.Show("停止採集失敗!"); } }
//關閉裝置 public void CloseDevice() { // ch:關閉裝置 | en:Close Device int nRet; nRet = m_pMyCamera.MV_CC_CloseDevice_NET(); if (MyCamera.MV_OK != nRet) { return; } nRet = m_pMyCamera.MV_CC_DestroyDevice_NET(); if (MyCamera.MV_OK != nRet) { return; } }
//讀取圖片轉換成Halcon影象 public HImage ReadImage() { int nRet; //MyCamera.MVCC_INTVALUE stParam = new MyCamera.MVCC_INTVALUE(); UInt32 nPayloadSize = 0; nRet = m_pMyCamera.MV_CC_GetIntValue_NET("PayloadSize", ref stParam); if (MyCamera.MV_OK != nRet) { return null; } nPayloadSize = stParam.nCurValue; if (nPayloadSize > m_nBufSizeForDriver) { m_nBufSizeForDriver = nPayloadSize; m_pBufForDriver = new byte[m_nBufSizeForDriver]; m_nBufSizeForSaveImage = m_nBufSizeForDriver * 3 + 2048; m_pBufForSaveImage = new byte[m_nBufSizeForSaveImage]; } IntPtr pData = Marshal.UnsafeAddrOfPinnedArrayElement(m_pBufForDriver, 0); MyCamera.MV_FRAME_OUT_INFO_EX stFrameInfo = new MyCamera.MV_FRAME_OUT_INFO_EX(); nRet = m_pMyCamera.MV_CC_GetOneFrameTimeout_NET(pData, m_nBufSizeForDriver, ref stFrameInfo, 1000);//獲取一幀影象,超時時間設定為1000 if (MyCamera.MV_OK != nRet) { return null; } HImage image = new HImage(); //採集的是黑白影象,利用Halcon影象庫中的GenImage1運算元來構建影象 image.GenImage1("byte", (int)stFrameInfo.nWidth, (int)stFrameInfo.nHeight, pData); return image; }
下面是我所做的一個表單介面,顯示裝置序列號的下拉選單做成了一個使用者控制元件,將上述的程式碼全部放在使用者控制元件中,在主表單裡呼叫使用者控制元件裡的方法來實現相機的連線和採集
具體見範例程式碼。
範例程式碼:
//查詢裝置 private void btnEnum_Click(object sender, EventArgs e) { ucDeviceList1.DeviceListAcq(); } //開啟裝置 private void btnOpen_Click(object sender, EventArgs e) { ucDeviceList1.OpenDevice(); btnOpen.Enabled = false; btnClose.Enabled = true; btnContinuesGrab.Enabled = true; //btnSingleStep.Enabled = true; btnStopGrab.Enabled = true; } //關閉裝置 private void btnClose_Click(object sender, EventArgs e) { ucDeviceList1.CloseDevice(); btnOpen.Enabled = true; btnClose.Enabled = false; btnContinuesGrab.Enabled = false; btnSingleStep.Enabled = false; btnStopGrab.Enabled = false; } //實時顯示 private void btnContinuesGrab_Click(object sender, EventArgs e) { ucDeviceList1.ContinuesGrab(picboxShowImg); btnContinuesGrab.Enabled = false; btnSingleStep.Enabled = true; btnStopGrab.Enabled = true; } //單步採集 private void btnSingleStep_Click(object sender, EventArgs e) { // 將採集到的影象在Halcon視窗中顯示 HTuple hWind = hWindowControl1.HalconWindow; HTuple width, height; HObject hv_image; HOperatorSet.GenEmptyObj(out hv_image); hv_image.Dispose(); hv_image = ucDeviceList1.ReadImage(); HOperatorSet.GetImageSize(hv_image, out width, out height); HOperatorSet.SetPart(hWind, 0, 0, height - 1, width - 1); HOperatorSet.DispObj(img, hWind); btnStopGrab.Enabled = true; } //停止採集 private void btnStopGrab_Click(object sender, EventArgs e) { ucDeviceList1.StopGrab(); btnContinuesGrab.Enabled = true; btnStopGrab.Enabled = false; } //關閉裝置 private void btnClose_Click(object sender, EventArgs e) { ucDeviceList1.CloseDevice(); btnOpen.Enabled = true; btnClose.Enabled = false; btnContinuesGrab.Enabled = false; btnSingleStep.Enabled = false; btnStopGrab.Enabled = false; }
注:上述方法是不需要修改相機IP的,但是要提前用MVS軟體修改相機的IP
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45