**
Usage record of raspberry pie 4b (I): use Python OpenCV to open Haikang industrial camera in raspberry pie 4b and the problems encountered and Solutions
**
1, Install MVS software (Linux version) of Haikang industrial robot on raspberry pie
Haikang industrial robot software download address:[ https://www.hikrobotics.com/cn/machinevision/service/download?module=0 ]After opening, find the required version as shown in the figure below.
Find the linux download installation package. I download MVS V2.1.0(Linux) here.
Click download to start downloading the installation package. After downloading, move the installation package to disk u and insert it into raspberry pie (here I use VNC software to control raspberry pie). Create a new file Linux MVS, and put the downloaded installation package into this folder
Unzip the downloaded files to get the following files. For raspberry pie, select two files in the file name armfhf. For linux PC, you can select x86_ 84. Jetson chooses aarch64. I386 is a 32-bit linux PC. there are two ways to install MVS software in linux, one can be used. Here I only introduce the installation method I use.
Open the terminal, enter the current folder through the cd command, and prepare to unzip the file.
Installation via dpkg package
Open the terminal, enter the current folder through the cd command, and run the following command: sudo dpkg – i MVS-2.1.0_armhf_20201228.deb. At this time, the MVS software is installed in the / opt/MVS path:
At this step, install MVS on raspberry pie!
2, Open Haikang industrial camera with Python opencv
To open Haikang industrial camera with python program, you need to call the. Py file in MVS software. The specific path is / opt/MVS/Samples/armhf/Python/MvImport. Open mvcameracontrol in this file_ Class.py file. Check this statement, MvCamCtrldll. This is the key to opening the industrial camera. It calls the dynamic link library
This statement calls the file in / opt/MVS/lib/armhf by default. The biggest problem in the actual program operation is also here. The difference between raspberry pie and Linux system call is also here. Raspberry pie does not automatically add the dynamic link path of MVS call. We need to manually add the dynamic link path. In order to prevent the call from failing, the file cannot be queried, such as the following error:
OSError:libGCBase_gcc46_v3_0.so:cannot open shared object file:No such file or directory.
If yes, we need to modify the files in the / etc/ld.so.conf.d directory of raspberry pie and add the path we want.
You can create a new file or add the path we need to the existing file. As shown in the figure:
After adding, save the file. If the permission is insufficient when modifying or querying a file, use the command "chmod 777 / file name" to modify the file permission. You can change the permission to anyone, so you can modify the file at will:
After saving, open the terminal and enter the sudo ldconfig command to complete the configuration.
Finally, run the program and you can see that the camera is turned on successfully.
3, Open the Haikang industrial camera under the jetson nano
Open this camera under the jetson nano, and the installation sequence of MVS installation package is the same as that under the raspberry pie, but the installation package is sudo dpkg – i MVS-2.1.0_aarch64_20201228.deb.
In the program, modify the statement sys.path.append("/opt/MVS/Samples/armhf/Python/MvImport") to sys.path.append("/ opt/MVS/Samples/aarch/Python/MvImport") (mainly the actual file name!)
Then check the files in the / etc/ld.so.conf.d directory to see if there are aarch64 related files. If there are, there is no need to modify them. If not, refer to the method of manually adding dynamic link paths to raspberry pie.
After that, you can run the program. If the failed to load module "Canberra get module" appears in the running program
Solution: open the terminal and enter sudo apt get install libcanberra GTK moudle. When the camera is turned on, the operation is as follows:
The main codes of the program are as follows:
import sys from ctypes import * import os import numpy as np import time #from Camera import Camera #from FTPService import FTPService #from GPIO_set import GPIO_set import cv2 #import configparser sys.path.append("/opt/MVS/Samples/armhf/Python/MvImport") #Open the MvImport file in MVS. For different systems, the open file path can follow the actual file path from MvCameraControl_class import * #Mvcameracontrol called_ Class.py file class HKCamera(): def __init__(self, CameraIdx=0, log_path=None): # enumerate all the camera devices deviceList = self.enum_devices() # generate a camera instance self.camera = self.open_camera(deviceList, CameraIdx, log_path) self.start_camera() def __del__(self): if self.camera is None: return # Stop taking flow ret = self.camera.MV_CC_StopGrabbing() if ret != 0: raise Exception("stop grabbing fail! ret[0x%x]" % ret) # Turn off the device ret = self.camera.MV_CC_CloseDevice() if ret != 0: raise Exception("close deivce fail! ret[0x%x]" % ret) # Destroy handle ret = self.camera.MV_CC_DestroyHandle() if ret != 0: raise Exception("destroy handle fail! ret[0x%x]" % ret) @staticmethod def enum_devices(device=0, device_way=False): """ device = 0 Enumerate network ports USB Port, unknown device cameralink equipment device = 1 enumeration GenTL equipment """ if device_way == False: if device == 0: cameraType = MV_GIGE_DEVICE | MV_USB_DEVICE | MV_UNKNOW_DEVICE | MV_1394_DEVICE | MV_CAMERALINK_DEVICE deviceList = MV_CC_DEVICE_INFO_LIST() # Enumerate devices ret = MvCamera.MV_CC_EnumDevices(cameraType, deviceList) if ret != 0: raise Exception("enum devices fail! ret[0x%x]" % ret) return deviceList else: pass elif device_way == True: pass def open_camera(self, deviceList, CameraIdx, log_path): # generate a camera instance camera = MvCamera() # Select the device and create a handle stDeviceList = cast(deviceList.pDeviceInfo[CameraIdx], POINTER(MV_CC_DEVICE_INFO)).contents if log_path is not None: ret = self.camera.MV_CC_SetSDKLogPath(log_path) if ret != 0: raise Exception("set Log path fail! ret[0x%x]" % ret) # Create handle and generate log ret = camera.MV_CC_CreateHandle(stDeviceList) if ret != 0: raise Exception("create handle fail! ret[0x%x]" % ret) else: # Create handle without generating log ret = camera.MV_CC_CreateHandleWithoutLog(stDeviceList) if ret != 0: raise Exception("create handle fail! ret[0x%x]" % ret) # Turn on the camera ret = camera.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0) if ret != 0: raise Exception("open device fail! ret[0x%x]" % ret) return camera def start_camera(self): stParam = MVCC_INTVALUE() memset(byref(stParam), 0, sizeof(MVCC_INTVALUE)) ret = self.camera.MV_CC_GetIntValue("PayloadSize", stParam) if ret != 0: raise Exception("get payload size fail! ret[0x%x]" % ret) self.nDataSize = stParam.nCurValue self.pData = (c_ubyte * self.nDataSize)() self.stFrameInfo = MV_FRAME_OUT_INFO_EX() memset(byref(self.stFrameInfo), 0, sizeof(self.stFrameInfo)) self.camera.MV_CC_StartGrabbing() def get_Value(self, param_type, node_name): """ :param cam: Camera instance :param_type: Get node value type :param node_name: Node name optional int ,float ,enum ,bool ,string Type node :return: Node value """ if param_type == "int_value": stParam = MVCC_INTVALUE_EX() memset(byref(stParam), 0, sizeof(MVCC_INTVALUE_EX)) ret = self.camera.MV_CC_GetIntValueEx(node_name, stParam) if ret != 0: raise Exception("obtain int Type data %s fail ! Error code ret[0x%x]" % (node_name, ret)) return stParam.nCurValue elif param_type == "float_value": stFloatValue = MVCC_FLOATVALUE() memset(byref(stFloatValue), 0, sizeof(MVCC_FLOATVALUE)) ret = self.camera.MV_CC_GetFloatValue(node_name, stFloatValue) if ret != 0: raise Exception("obtain float Type data %s fail ! Error code ret[0x%x]" % (node_name, ret)) return stFloatValue.fCurValue elif param_type == "enum_value": stEnumValue = MVCC_ENUMVALUE() memset(byref(stEnumValue), 0, sizeof(MVCC_ENUMVALUE)) ret = self.camera.MV_CC_GetEnumValue(node_name, stEnumValue) if ret != 0: raise Exception("obtain enum Type data %s fail ! Error code ret[0x%x]" % (node_name, ret)) return stEnumValue.nCurValue elif param_type == "bool_value": stBool = c_bool(False) ret = self.camera.MV_CC_GetBoolValue(node_name, stBool) if ret != 0: raise Exception("obtain bool Type data %s fail ! Error code ret[0x%x]" % (node_name, ret)) return stBool.value elif param_type == "string_value": stStringValue = MVCC_STRINGVALUE() memset(byref(stStringValue), 0, sizeof(MVCC_STRINGVALUE)) ret = self.camera.MV_CC_GetStringValue(node_name, stStringValue) if ret != 0: raise Exception("obtain string Type data %s fail ! Error code ret[0x%x]" % (node_name, ret)) return stStringValue.chCurValue else: return None def set_Value(self, param_type, node_name, node_value): """ :param cam: Camera instance :param param_type: Node type to be set int: float: enum: Refer to this option in the client Enum Entry Value Value bool: Corresponding 0 is off and 1 is on string: The input value is numeric or English characters, not Chinese characters :param node_name: Node name to be set :param node_value: The value set to the node :return: """ if param_type == "int_value": ret = self.camera.MV_CC_SetIntValueEx(node_name, int(node_value)) if ret != 0: raise Exception("set up int Type data node %s fail ! Error code ret[0x%x]" % (node_name, ret)) elif param_type == "float_value": ret = self.camera.MV_CC_SetFloatValue(node_name, float(node_value)) if ret != 0: raise Exception("set up float Type data node %s fail ! Error code ret[0x%x]" % (node_name, ret)) elif param_type == "enum_value": ret = self.camera.MV_CC_SetEnumValue(node_name, node_value) if ret != 0: raise Exception("set up enum Type data node %s fail ! Error code ret[0x%x]" % (node_name, ret)) elif param_type == "bool_value": ret = self.camera.MV_CC_SetBoolValue(node_name, node_value) if ret != 0: raise Exception("set up bool Type data node %s Failed! Error code ret[0x%x]" % (node_name, ret)) elif param_type == "string_value": ret = self.camera.MV_CC_SetStringValue(node_name, str(node_value)) if ret != 0: raise Exception("set up string Type data node %s fail ! Error code ret[0x%x]" % (node_name, ret)) def set_exposure_time(self, exp_time): self.set_Value(param_type="float_value", node_name="ExposureTime", node_value=exp_time) def get_exposure_time(self): return self.get_Value(param_type="float_value", node_name="ExposureTime") def get_image(self, width=None): """ :param cam: Camera instance :active_way:The different methods of active current collection are( getImagebuffer)(getoneframetimeout) :return: """ ret = self.camera.MV_CC_GetOneFrameTimeout(self.pData, self.nDataSize, self.stFrameInfo, 1000) if ret == 0: image = np.asarray(self.pData).reshape((self.stFrameInfo.nHeight, self.stFrameInfo.nWidth)) if width is not None: image = cv2.resize(image, (width, int(self.stFrameInfo.nHeight * width / self.stFrameInfo.nWidth))) pass return image else: return None def show_runtime_info(self, image): exp_time = self.get_exposure_time() cv2.putText(image, ("exposure time = %1.1fms" % (exp_time * 0.001)), (20, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.5, 255, 1) if __name__ == '__main__': camera = HKCamera() try: while True: image = camera.get_image(width=800) if image is not None: camera.show_runtime_info(image) cv2.imshow("", image) key = cv2.waitKey(50) & 0xFF if key == ord('e') or key == ord('E'): cv2.destroyAllWindows() break except Exception as e: print(e)
Refer to the great God article:
Method of adding dynamic link library path under linux: https://www.cnblogs.com/ostin/p/9193029.html.
Record of ROS packge process of secondary development and packaging of Haikang Camera MVS Linux SDK (c + +): https://blog.csdn.net/weixin_41965898/article/details/116801491.
python calls Haikang industrial camera and displays it with opencv (overall implementation, under windows): https://blog.csdn.net/qq_39570716/article/details/114066097?spm=1001.2014.3001.5501.