接上文ocr PaddleOCR(use_angle_clsTrue,use_gpuTrue, langen) ocr2 PaddleOCR(use_angle_clsFalse, use_gpuTrue, langen)初始化两个PaddleOCR识别器对象用于文字识别。第一个识别器是启用文字方向分类器其实就是自动检测并纠正一些倾斜旋转的文字适合识别角度不确定的图片但是识别速度就会下降并且使用GPU加速识别的是英文第二个没有启用方向分类器进行识别。首次识别进行角度矫正所以第二次识别的时候图片角度已经正确。双重识别结果更可靠。接下来介绍的函数都是定义在类class PyQtMainEntry(QMainWindow, Ui_MainWindow)中的一、初始化这个初始化方法设置了3个摄像头的识别系统对应到之前提到的3组OCR识别函数def __init__(self): super().__init__() self.setupUi(self)继承父类初始化然后加载UI界面这里使用的是pyqt中designer生成的界面self.ser1 serial.Serial(opt.SERIAL_PORT1, 9600, timeout2.5) self.ser2 serial.Serial(opt.SERIAL_PORT2, 9600, timeout2.5) # self.ser3 serial.Serial(opt.SERIAL_PORT3, 9600, timeout2.5)串口连接其实就是报警器控制。连接了两个报警器self.label_4.setVisible(False) self.label_5.setVisible(False) self.label_6.setVisible(False)UI标签初始化隐藏了3个警告标签对应了3个摄像头识别到违规零件才显示。self.list_zong1 []# 存储OCR识别结果列表 self.list_zong2 [] self.list_zong3 [] self.set_zong1 set()# 存储标准化后的结果集合 self.set_zong2 set() self.set_zong3 set() self.set_12hun set()# 可能是存储合格/白名单 self.guo []# 存储过程/中间结果 self.list1 []# 临时列表1 self.list2 [] self.list3 [] self.daan1 # 答案/结果1 self.daan2 # self.showMaximized()数据存储结构有三组每组都有独立的存储空间对应三个摄像头。list_zong是原始识别结果。set-zong是标准化后的结果。# 第一个摄像头 self.camera1 HKCamera(CameraIp192.168.20.30) self.camera1.set_Value(param_typeenum_value, node_namePixelFormat, node_valueBayerGB8) self.camera1.set_Value(param_typeenum_value, node_nameGainAuto, node_valueContinuous) self.camera1.set_Value(param_typefloat_value, node_nameAcquisitionFrameRate, node_value15.0000) # self.camera1.set_Value(param_typeenum_value, node_nameExposureAuto, # node_valueContinuous) # 自动曝光 self.camera1.start_camera() # 第二个摄像头 self.camera2 HKCamera(CameraIp192.168.20.20) self.camera2.set_Value(param_typeenum_value, node_namePixelFormat, node_valueBayerGB8) self.camera2.set_Value(param_typeenum_value, node_nameGainAuto, node_valueContinuous) self.camera2.set_Value(param_typefloat_value, node_nameAcquisitionFrameRate, node_value15.0000) # self.camera2.set_Value(param_typeenum_value, node_nameExposureAuto, # node_valueContinuous) #自动曝光 # self.camera2.set_Value(param_typeenum_value, node_nameDecimationHorizontal, # node_value2) # self.camera2.set_Value(param_typeenum_value, node_nameDecimationVertical, # node_value2) self.camera2.start_camera()摄像头初始化这里是两个海康工业相机这两个配置几乎是一样的。ip地址在同一网段下像素格式BayerGB8增益自动连续帧率15帧每秒都是一样的#第三个摄像头 self.camera3 cv2.VideoCapture(opt.cap_numb3) # 启动后台线程来定期释放第三个摄像头的资源 release_thread2 threading.Thread(targetrelease_capture3, args(self.camera3,)) release_thread2.daemon True # 设置为守护线程随主线程结束而结束 release_thread2.start() #定时器设置 self.is_camera_opened False self._timer QtCore.QTimer(self) self._timer.timeout.connect(self._queryFrame) self._timer.setInterval(opt.frame_delay) self.frame_counter 0 # 统计画面的帧数摄像头三就是普通的USB摄像头使用opencv的videoCapture。然后就是摄像头3的资源维护线程。启动守护线程每三十分钟重启一次USB摄像头。定时器设置Qt定时器定时获取摄像头画面67ms间隔相当于15帧/秒。预工业相机的帧率匹配。这是一个三路并行识别系统每个摄像头独立识别零件编码发现违规时通过串口控制报警器报警。二、控制视频识别开关的按钮回调正割函数控制整个识别系统的启动和停止类似于开始监控/停止监控按钮。def openvideo(self): # 1. 切换摄像头状态开/关 self.is_camera_opened not self.is_camera_opened if self.is_camera_opened: # 2. 开启识别模式 self.pushButton_4.setText(关闭)# 按钮文字改为关闭 self._timer.start()# 启动定时器开始识别 else: # 3. 关闭识别模式 self.pushButton_4.setText(打开)# 按钮文字改为打开 self._timer.stop()# 停止定时器 # 4. 关闭所有报警器 sendCmdToDevice(BUZZ_CMD_CLOSE, self.ser1)# 关闭报警器1 sendCmdToDevice(BUZZ_CMD_CLOSE, self.ser2)# 关闭报警器2 # sendCmdToDevice(BUZZ_CMD_CLOSE, self.ser3) # 5. 隐藏所有警告标签 self.label_4.setVisible(False)# 隐藏摄像头1的警告 self.label_5.setVisible(False) self.label_6.setVisible(False)开始识别时状态切换为True按钮文字变为关闭启动定时器开始不断调用_queryFrame获取图像并识别。关闭识别时状态切换为False按钮文字变为打开停止定时器就停止了识别发送关闭命令停止所有将抱起的声音和闪光隐藏所有警告标签中指界面状态。这个函数和介绍类之前的函数的关联_timer定时器控制识别频率sendCmdToDevice函数控制报警器label_4/5/6用来显示3个摄像头的警告self.is_camera_opened全局状态标志。其实这个函数就是界面设计的函数对吧里面用到的函数就是我们对按钮自定义的函数。三、打开文件夹-复位按钮一-复位按钮二-装饰器def open_folder(self): folder_path rD:\MVS\MVS\Development\Samples\Python\shiyan\baojing QDesktopServices.openUrl(QUrl.fromLocalFile(folder_path)) def clearSet1(self): # 复位按钮一 self.set_zong1.clear() # self.list_zong1.clear() self.list1.clear() sendCmdToDevice(BUZZ_CMD_CLOSE, self.ser1) self.label_4.setVisible(False) def clearSet2(self): # 复位按钮二 self.set_zong2.clear() # self.list_zong2.clear() self.list2.clear() sendCmdToDevice(BUZZ_CMD_CLOSE, self.ser2) self.label_5.setVisible(False) def execute_after_n_calls(n, w2set): def decorator(func): def wrapper(self, *args, **kwargs): wrapper.count 1 result func(self, *args, **kwargs) if wrapper.count % n 0: w2set(self) return result wrapper.count 0 return wrapper return decorator函数一在文件管理器中打开指定的文件夹函数二重置摄像头1的识别状态清除已识别的数据并停止报警隐藏警告图标。函数三和函数二一样只不过这里对应的是摄像头2函数四装饰器工厂用于限制函数执行频率两个参数n是调用多少次后才触发w2set是达到次数后执行的回调函数每调用一次被装饰的函数计数器就会1当计数是n的倍数时执行w2set。这个装饰器的目的是提高准确率累计多次识别结果取众数后再显示、减少界面刷新不是每次识别都更新降低CPU/GPU负载、平滑显示避免识别结果频繁闪烁变化、投票机制就像之前讲一个零件识别多次取可靠的。这是一个稳定的工业识别系统的设计模式兼顾实时性和准确性。
1112334
接上文ocr PaddleOCR(use_angle_clsTrue,use_gpuTrue, langen) ocr2 PaddleOCR(use_angle_clsFalse, use_gpuTrue, langen)初始化两个PaddleOCR识别器对象用于文字识别。第一个识别器是启用文字方向分类器其实就是自动检测并纠正一些倾斜旋转的文字适合识别角度不确定的图片但是识别速度就会下降并且使用GPU加速识别的是英文第二个没有启用方向分类器进行识别。首次识别进行角度矫正所以第二次识别的时候图片角度已经正确。双重识别结果更可靠。接下来介绍的函数都是定义在类class PyQtMainEntry(QMainWindow, Ui_MainWindow)中的一、初始化这个初始化方法设置了3个摄像头的识别系统对应到之前提到的3组OCR识别函数def __init__(self): super().__init__() self.setupUi(self)继承父类初始化然后加载UI界面这里使用的是pyqt中designer生成的界面self.ser1 serial.Serial(opt.SERIAL_PORT1, 9600, timeout2.5) self.ser2 serial.Serial(opt.SERIAL_PORT2, 9600, timeout2.5) # self.ser3 serial.Serial(opt.SERIAL_PORT3, 9600, timeout2.5)串口连接其实就是报警器控制。连接了两个报警器self.label_4.setVisible(False) self.label_5.setVisible(False) self.label_6.setVisible(False)UI标签初始化隐藏了3个警告标签对应了3个摄像头识别到违规零件才显示。self.list_zong1 []# 存储OCR识别结果列表 self.list_zong2 [] self.list_zong3 [] self.set_zong1 set()# 存储标准化后的结果集合 self.set_zong2 set() self.set_zong3 set() self.set_12hun set()# 可能是存储合格/白名单 self.guo []# 存储过程/中间结果 self.list1 []# 临时列表1 self.list2 [] self.list3 [] self.daan1 # 答案/结果1 self.daan2 # self.showMaximized()数据存储结构有三组每组都有独立的存储空间对应三个摄像头。list_zong是原始识别结果。set-zong是标准化后的结果。# 第一个摄像头 self.camera1 HKCamera(CameraIp192.168.20.30) self.camera1.set_Value(param_typeenum_value, node_namePixelFormat, node_valueBayerGB8) self.camera1.set_Value(param_typeenum_value, node_nameGainAuto, node_valueContinuous) self.camera1.set_Value(param_typefloat_value, node_nameAcquisitionFrameRate, node_value15.0000) # self.camera1.set_Value(param_typeenum_value, node_nameExposureAuto, # node_valueContinuous) # 自动曝光 self.camera1.start_camera() # 第二个摄像头 self.camera2 HKCamera(CameraIp192.168.20.20) self.camera2.set_Value(param_typeenum_value, node_namePixelFormat, node_valueBayerGB8) self.camera2.set_Value(param_typeenum_value, node_nameGainAuto, node_valueContinuous) self.camera2.set_Value(param_typefloat_value, node_nameAcquisitionFrameRate, node_value15.0000) # self.camera2.set_Value(param_typeenum_value, node_nameExposureAuto, # node_valueContinuous) #自动曝光 # self.camera2.set_Value(param_typeenum_value, node_nameDecimationHorizontal, # node_value2) # self.camera2.set_Value(param_typeenum_value, node_nameDecimationVertical, # node_value2) self.camera2.start_camera()摄像头初始化这里是两个海康工业相机这两个配置几乎是一样的。ip地址在同一网段下像素格式BayerGB8增益自动连续帧率15帧每秒都是一样的#第三个摄像头 self.camera3 cv2.VideoCapture(opt.cap_numb3) # 启动后台线程来定期释放第三个摄像头的资源 release_thread2 threading.Thread(targetrelease_capture3, args(self.camera3,)) release_thread2.daemon True # 设置为守护线程随主线程结束而结束 release_thread2.start() #定时器设置 self.is_camera_opened False self._timer QtCore.QTimer(self) self._timer.timeout.connect(self._queryFrame) self._timer.setInterval(opt.frame_delay) self.frame_counter 0 # 统计画面的帧数摄像头三就是普通的USB摄像头使用opencv的videoCapture。然后就是摄像头3的资源维护线程。启动守护线程每三十分钟重启一次USB摄像头。定时器设置Qt定时器定时获取摄像头画面67ms间隔相当于15帧/秒。预工业相机的帧率匹配。这是一个三路并行识别系统每个摄像头独立识别零件编码发现违规时通过串口控制报警器报警。二、控制视频识别开关的按钮回调正割函数控制整个识别系统的启动和停止类似于开始监控/停止监控按钮。def openvideo(self): # 1. 切换摄像头状态开/关 self.is_camera_opened not self.is_camera_opened if self.is_camera_opened: # 2. 开启识别模式 self.pushButton_4.setText(关闭)# 按钮文字改为关闭 self._timer.start()# 启动定时器开始识别 else: # 3. 关闭识别模式 self.pushButton_4.setText(打开)# 按钮文字改为打开 self._timer.stop()# 停止定时器 # 4. 关闭所有报警器 sendCmdToDevice(BUZZ_CMD_CLOSE, self.ser1)# 关闭报警器1 sendCmdToDevice(BUZZ_CMD_CLOSE, self.ser2)# 关闭报警器2 # sendCmdToDevice(BUZZ_CMD_CLOSE, self.ser3) # 5. 隐藏所有警告标签 self.label_4.setVisible(False)# 隐藏摄像头1的警告 self.label_5.setVisible(False) self.label_6.setVisible(False)开始识别时状态切换为True按钮文字变为关闭启动定时器开始不断调用_queryFrame获取图像并识别。关闭识别时状态切换为False按钮文字变为打开停止定时器就停止了识别发送关闭命令停止所有将抱起的声音和闪光隐藏所有警告标签中指界面状态。这个函数和介绍类之前的函数的关联_timer定时器控制识别频率sendCmdToDevice函数控制报警器label_4/5/6用来显示3个摄像头的警告self.is_camera_opened全局状态标志。其实这个函数就是界面设计的函数对吧里面用到的函数就是我们对按钮自定义的函数。三、打开文件夹-复位按钮一-复位按钮二-装饰器def open_folder(self): folder_path rD:\MVS\MVS\Development\Samples\Python\shiyan\baojing QDesktopServices.openUrl(QUrl.fromLocalFile(folder_path)) def clearSet1(self): # 复位按钮一 self.set_zong1.clear() # self.list_zong1.clear() self.list1.clear() sendCmdToDevice(BUZZ_CMD_CLOSE, self.ser1) self.label_4.setVisible(False) def clearSet2(self): # 复位按钮二 self.set_zong2.clear() # self.list_zong2.clear() self.list2.clear() sendCmdToDevice(BUZZ_CMD_CLOSE, self.ser2) self.label_5.setVisible(False) def execute_after_n_calls(n, w2set): def decorator(func): def wrapper(self, *args, **kwargs): wrapper.count 1 result func(self, *args, **kwargs) if wrapper.count % n 0: w2set(self) return result wrapper.count 0 return wrapper return decorator函数一在文件管理器中打开指定的文件夹函数二重置摄像头1的识别状态清除已识别的数据并停止报警隐藏警告图标。函数三和函数二一样只不过这里对应的是摄像头2函数四装饰器工厂用于限制函数执行频率两个参数n是调用多少次后才触发w2set是达到次数后执行的回调函数每调用一次被装饰的函数计数器就会1当计数是n的倍数时执行w2set。这个装饰器的目的是提高准确率累计多次识别结果取众数后再显示、减少界面刷新不是每次识别都更新降低CPU/GPU负载、平滑显示避免识别结果频繁闪烁变化、投票机制就像之前讲一个零件识别多次取可靠的。这是一个稳定的工业识别系统的设计模式兼顾实时性和准确性。