海康威视工业相机使用
需要用攝像頭,而實驗室只有一個海康威視的MV-CA013-20GC(另一個大恒的更難搞),拿工業相機當普通相機用是不是有點暴殄天物了。
?
1. 相機接線
工業相機一般都需要獨立供電,12v接上相機的正負極,另外網口接上電腦或交換機Lan口,建議使用千兆網口,不然幀率跟不上(也可以使用網口轉usb3.0).
2.客戶端使用
去官網下載下面兩個軟件安裝,一個是客戶端,另一個是開發運行環境。
打開軟件如圖所示
軟件會自動搜索可連接的設備,查找到設備后修改相機的ip,連接上相機,然后就可以調節參數了。這里如果畫面很黑,首先調小相機的光圈,增大進光量,開啟自動曝光與自動增益、伽馬校正。如果使用的百兆網口會出現幀率低的情況,這里要么就更換千兆網口,要么將圖像類型設置為mono8.
3.sdk的二次開發
進入到安裝目錄下有一個Development文件夾,里面有頭文件和庫文件以及各種語言的開發說明和demo。
這里以C++為例(VS2019)
大致流程如下,具體實現請參考文檔和demo
首先新建項目,將開發需要的頭文件和庫文件拷出來放到項目文件中,注意庫文件有32和64之分。在屬性里面配置頭文件和庫文件。如圖所示
示例代碼,先捕獲攝像頭圖像,再用opencv顯示
#include "MvCameraControl.h" #include "opencv2/opencv.hpp"#include <stdio.h> #include <conio.h> #include <iostream> #include <string>using namespace std;bool printDeviceInfo(MV_CC_DEVICE_INFO* hk_device); bool hk2cv(MV_FRAME_OUT_INFO_EX* hk_imginfo, unsigned char* data, cv::Mat &src_img);int main(int argv, char** argc) {int ret = MV_OK;void* handle = NULL;MV_CC_DEVICE_INFO_LIST hk_devices;memset(&hk_devices, 0, sizeof(MV_CC_DEVICE_INFO_LIST));ret = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &hk_devices);if (ret != MV_OK) {cout << "enum devices faild!" << endl;return -1;}if (hk_devices.nDeviceNum > 0) {MV_CC_DEVICE_INFO* hk_camera = hk_devices.pDeviceInfo[0];if (printDeviceInfo(hk_camera) == false) {return -1;}}else {cout << "no device found" << endl;return -1;}ret = MV_CC_CreateHandle(&handle, hk_devices.pDeviceInfo[0]);if (ret != MV_OK) {return -1;}ret = MV_CC_OpenDevice(handle);if (ret != MV_OK) {return -1;}ret = MV_CC_SetEnumValue(handle, "TriggerMode", 0);if (ret != MV_OK) {return -1;}MVCC_INTVALUE hk_param;memset(&hk_param, 0, sizeof(MVCC_INTVALUE));ret = MV_CC_GetIntValue(handle, "PayloadSize", &hk_param);if (ret != MV_OK) {return -1;}unsigned int payload_size = hk_param.nCurValue;// load configret = MV_CC_FeatureLoad(handle, "FeatureFile.ini");if (ret != MV_OK){cout << "loading config file faild" << endl;return -1;}// save config/* ret = MV_CC_FeatureSave(handle, "FeatureFile.ini");if (ret != MV_OK) {return -1;}*/// start grabbing imagesret = MV_CC_StartGrabbing(handle);if (ret != MV_OK) {cout << "grab image failed!" << endl;return -1;}MV_FRAME_OUT_INFO_EX hk_imginfo;memset(&hk_imginfo, 0, sizeof(MV_FRAME_OUT_INFO_EX));unsigned char* data = (unsigned char*)malloc(sizeof(unsigned char) * (payload_size));if (data == NULL) {return -1;}cv::Mat src_img;while (!(_kbhit() && _getch() == 0x1b)) {ret = MV_CC_GetOneFrameTimeout(handle, data, payload_size, &hk_imginfo, 1000);if (ret != MV_OK) {free(data);data = NULL;return -1;}if (hk2cv(&hk_imginfo, data, src_img) == false) {continue;}cv::imshow("test", src_img);cv::waitKey(30);}// stop grap imageret = MV_CC_StopGrabbing(handle);if (ret != MV_OK) {return -1;}// close deviceret = MV_CC_CloseDevice(handle);if (ret != MV_OK) {return -1;}ret = MV_CC_DestroyHandle(handle);if (ret != MV_OK) {return -1;}system("pause");return 0; }bool printDeviceInfo(MV_CC_DEVICE_INFO* hk_device) {if (NULL == hk_device){printf("The Pointer of hk_device is NULL!\n");return false;}if (hk_device->nTLayerType == MV_GIGE_DEVICE){int nIp1 = ((hk_device->SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24);int nIp2 = ((hk_device->SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16);int nIp3 = ((hk_device->SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8);int nIp4 = (hk_device->SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff);// print current ip and user defined nameprintf("CurrentIp: %d.%d.%d.%d\n", nIp1, nIp2, nIp3, nIp4);printf("UserDefinedName: %s\n\n", hk_device->SpecialInfo.stGigEInfo.chUserDefinedName);}else if (hk_device->nTLayerType == MV_USB_DEVICE){printf("UserDefinedName: %s\n", hk_device->SpecialInfo.stUsb3VInfo.chUserDefinedName);printf("Serial Number: %s\n", hk_device->SpecialInfo.stUsb3VInfo.chSerialNumber);printf("Device Number: %d\n\n", hk_device->SpecialInfo.stUsb3VInfo.nDeviceNumber);}else{printf("Not support.\n");}return true; }bool hk2cv(MV_FRAME_OUT_INFO_EX* hk_imginfo, unsigned char* data, cv::Mat& src_img) {cv::Mat cv_img;if (hk_imginfo->enPixelType == PixelType_Gvsp_Mono8){cv_img = cv::Mat(hk_imginfo->nHeight, hk_imginfo->nWidth, CV_8UC1, data);}else if (hk_imginfo->enPixelType == PixelType_Gvsp_RGB8_Packed){for (unsigned int j = 0; j < hk_imginfo->nHeight; j++){for (unsigned int i = 0; i < hk_imginfo->nWidth; i++){unsigned char red = data[j * (hk_imginfo->nWidth * 3) + i * 3];data[j * (hk_imginfo->nWidth * 3) + i * 3] = data[j * (hk_imginfo->nWidth * 3) + i * 3 + 2];data[j * (hk_imginfo->nWidth * 3) + i * 3 + 2] = red;}}cv_img = cv::Mat(hk_imginfo->nHeight, hk_imginfo->nWidth, CV_8UC3, data);}else{printf("unsupported pixel format\n");return false;}if (cv_img.data == NULL){return false;}cv_img.copyTo(src_img);return true; }因為每次斷電后都要重新設置,這里我取了一個巧,先用客戶端配置好參數,然后保存參數,以后每次運行只要加載參數就行了。如果運行提示沒有找到dll文件,那么就是你runtime運行環境沒有安裝,或者沒有將安裝路徑添加到系統環境變量。
?
正如開頭所說的,只是拿來當普通攝像頭用,所以代碼很簡單,后面有機會再深入研究。
總結
以上是生活随笔為你收集整理的海康威视工业相机使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 线性规划图解法求最优解_线性规划的图解法
- 下一篇: 迅雷协议分析