资讯动态

零件分拣项目实战

发布时间:2026/10/15 15:38:12 来源:尧图企业网站定制
任务设计一个识别零件标签的系统检测出错误时会发出警告声并保存错误截图。思路根据实际工厂流水线流程将检测流程分为3部分第一步检测被粘贴的零件标签码中的指定编号如某系列零件编号为V0-64具体通过paddleocr对摄像头中字符进行识别然后通过re正则编码面积编码坐标对识别的信息进行指定筛选。三个摄像头的画面都是统一15帧/s每个摄像头对应的画面每ocr识别三次数据作为当前的结果会将每10秒内检测出的最多编码作为当前画面的“正确目标”如果各自出现混料也就是出现与各自“正确目标”不一致的编码此时就会报警同时截图。目的就是过滤一些偶尔一帧画面识别出错误结果。这里不是识别帧的全部区域而是中间区域为了避免编码只有一半在每一帧中。第二步检测零件包装盒上的编号如包装盒上编号为V0-64具体通过paddleocr对摄像头中字符进行识别然后通过re正则编码面积编码坐标对识别的信息进行指定筛选。三个摄像头的画面都是统一15帧/s每个摄像头对应的画面每ocr识别三次数据作为当前的结果会将每10秒内检测出的最多编码作为当前画面的“正确目标”如果各自出现混料也就是出现与各自“正确目标”不一致的编码此时就会报警同时截图。目的就是过滤一些偶尔一帧画面识别出错误结果。这里不是识别帧的全部区域而是中间区域为了避免编码只有一半在每一帧中。第三步检测将零件盒打包至纸箱上的编号与第一部和第二部上的编号是否一致。具体通过paddleocr对摄像头中字符进行识别然后通过re正则编码面积编码坐标对识别的信息进行指定筛选。这里对检测结果评判与上两步不同的是依据第一步和第二步检测的正确目标二者相同与此处检测的结果对比若不相同则触发报警同时截图。这里不是识别帧的全部区域而是中间区域为了避免编码只有一半在每一帧中。接下来开始介绍整个项目注意1、这里采用的摄像头为海康摄像头。警告类别如下LIGHT_BUZZ1 0110001A000101CE18 # 闪光声音1 LIGHT_BUZZ2 0110001A0001040E1B # 闪光声音1 LIGHT 0110001A0001028E19 # 闪光 BUZZ1 0110001A0001034FD9 # 声音1 BUZZ2 0110001A000105CFDB # 声音2 BUZZ_CMD_CLOSE 0110001A0001000FD8 # 关闭声音和闪光2、对识别出的字符进行了替换上图为3个摄像头检测示例发现第三个摄像头检测易出错如将‘L’和1,l和1,0和o等识别错误。这里将数字0 → 字母o小写o → 大写O,字母S → 数字5,字母I → 数字1,字母L → 数字1,小写v → 大写V,字母B → 数字8,小写p → 大写P进行了替换。3、正则表达式如下(r^(?.*[a-zA-Z])(?.*\d)[a-zA-Z\d-]{2,10}$)摄像头1def w2set1(self): if self.list_zong1: try: for i in self.list_zong1: if self.list_zong1.count(i) 1: self.set_zong1.add(i) set_len1 set_bing(self.set_zong1) # 当前检测的结果 self.list1.extend(list(set_len1)) self.daan1 most_common_element(self.list1) # 标准答案 if self.frame_counter % 16 0: # 约每 10 秒刷新一下 self.list1.clear() text ,.join(set_len1) self.lineEdit.setText(text) # 做判断 if (not self.daan1) or (not set_len1): pass elif len(set_len1) 1 and (list(set_len1)[0] self.daan1): pass else: print(一) print(set_len1, self.daan1) tu1 cv2.putText(self.frame1.copy(), text, (100, 200), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 5, cv2.LINE_AA) nam time.strftime(%Y_%m_%d_%H_%M, time.localtime()) path os.path.join(rD:\MVS\MVS\Development\Samples\Python\shiyan\baojing\镜头一, f{nam}-{self.daan1}.jpg) cv2.imencode(.jpg, tu1)[1].tofile(path) self.label_4.setVisible(True) # 显示⚠符号 # sendCmdToDevice(LIGHT_BUZZ1, self.ser1) sendCmdToDevice(LIGHT, self.ser1) QtCore.QTimer.singleShot(5000, lambda: hide_label_and_send_cmd(self.label_4,self.ser1)) # 相当于格外线程计时5s后隐藏⚠并停止报警 # self.list_zong1.clear() # self.set_zong1.clear() self.frame_counter 0 except Exception as e: print(e) self.list_zong1.clear() self.set_zong1.clear() execute_after_n_calls(3, w2set1) def _performOCR1(self): result ocr2.ocr(self.frame1, clsFalse) if result and not None in result: try: for i in result[0]: # print(i) mianji are(i) # print(yi,i,mianji) ma process_string(i[1][0]) # if i[1][1] 0.92 and ma and 80i[0][0][0]550 and mianji1000: if i[1][1] 0.92 and ma and 320 i[0][0][0] 1060 and mianji 1000: self.list_zong1.extend(ma) # print(i[1][0], are(i)) # print(******************) except: pass执行3次_performOCR1才执行w2set1。_performOCR1执行了不断从3个摄像头取帧显示在qt界面上ocr识别的操作。w2set1执行了对摄像头1的检测结果去重选出正确结果判断置信度是否大于0.92检测出的坐标是否在320~1060之间字符面积是否大于1000是否警告的操作。摄像头2def w2set2(self): if self.list_zong2: try: for i in self.list_zong2: if self.list_zong2.count(i) 1: self.set_zong2.add(i) set_len2 set_bing(self.set_zong2) self.list2.extend(list(set_len2)) self.daan2 most_common_element(self.list2) if self.frame_counter % 25 0: # 约每 10 秒刷新一下 self.list2.clear() text2 ,.join(set_len2) self.lineEdit_2.setText(text2) if (not self.daan2) or (not set_len2): pass elif len(set_len2)1 and (list(set_len2)[0] self.daan2): pass else: print(二) print(set_len2, self.daan2) tu2 cv2.putText(self.frame2.copy(), text2, (100, 200), cv2.FONT_HERSHEY_SIMPLEX, 3, (0, 0, 255), 6, cv2.LINE_AA) nam2 time.strftime(%Y_%m_%d_%H_%M, time.localtime()) path os.path.join(rD:\MVS\MVS\Development\Samples\Python\shiyan\baojing\镜头二, f{nam2}-{self.daan2}.jpg) cv2.imencode(.jpg, tu2)[1].tofile(path) self.label_5.setVisible(True) # sendCmdToDevice(LIGHT_BUZZ1, self.ser2) sendCmdToDevice(LIGHT, self.ser2) QtCore.QTimer.singleShot(5000, lambda: hide_label_and_send_cmd(self.label_5, self.ser2)) # self.list_zong2.clear() # self.set_zong2.clear() self.frame_counter 0 except Exception as e: print(e) self.list_zong2.clear() self.set_zong2.clear() # self.set_12hun.add(self.daan1) # self.set_12hun.add(self.daan2) self.set_12hunset([self.daan1,self.daan2]) print(1:, self.daan1) print(2:, self.daan2) print(合:, self.set_12hun) execute_after_n_calls(3, w2set2) def _performOCR2(self): # 执行OCR操作 result2 ocr2.ocr(self.frame2, clsFalse) if result2 and not None in result2: try: for i in result2[0]: mianjiare(i) # print(er,mianji,i) maprocess_string(i[1][0]) if i[1][1] 0.84 and ma and mianji1600 and (350i[0][0][0]1060): #25000 self.list_zong2.extend(ma) # print(i,are(i),xie(i)) except: pass elif None in result2: self.daan2 self.set_12hun set([self.daan1, self.daan2]) print(1:, self.daan1) print(2:, self.daan2) print(合:, self.set_12hun)执行3次_performOCR2才执行w2set2。_performOCR2执行了不断从3个摄像头取帧显示在qt界面上ocr识别的操作。w2set2执行了对摄像头1的检测结果去重选出正确结果判断置信度是否大于0.84检测出的坐标是否在350~1060之间字符面积是否大于1000是否警告的操作。摄像头3def w2set3(self): maxx 0 if self.list_zong3: try: for i in self.list_zong3: self.guo.append(i[1][0]) for ii in self.guo: if self.guo.count(ii) 1: self.set_zong3.add(ii) # print(YYYY,self.set_zong3) for j in self.list_zong3: if (j[1][0] in self.set_zong3) and (are(j) maxx): aa j maxx are(j) text3 aa[1][0].replace(0, O).replace(o, O).replace(S, 5).replace(I, 1).replace(L,1).replace(v,V).replace(B,8).replace(p,P) self.lineEdit_3.setText(text3) if (not text3) or self.set_12hunset() or self.set_12hun{}: pass elif self.set_12hun and In_which(text3,self.set_12hun): pass else: print(三) print(text3) print(self.set_12hun) tu3 cv2.putText(self.frame3.copy(), text3, (100, 200), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 5, cv2.LINE_AA) nam3 time.strftime(%Y_%m_%d_%H_%M, time.localtime()) path os.path.join(rD:\MVS\MVS\Development\Samples\Python\shiyan\baojing\镜头三, f{nam3}-{self.set_12hun}.jpg) cv2.imencode(.jpg, tu3)[1].tofile(path) self.set_12hun.clear() self.label_6.setVisible(True) # sendCmdToDevice(LIGHT_BUZZ1, self.ser3) sendCmdToDevice(LIGHT, self.ser2) QtCore.QTimer.singleShot(5000, lambda: hide_label_and_send_cmd(self.label_6, self.ser2)) # self.list_zong3.clear() except: pass self.guo.clear() self.list_zong3.clear() self.set_zong3.clear() execute_after_n_calls(3, w2set3) def _performOCR3(self): global text3 # result2 ocr2.ocr(self.frame3, clsFalse) try: # 将图像从BGR转换为HSV颜色空间 hsv_image cv2.cvtColor(self.frame3, cv2.COLOR_BGR2HSV) # 定义牛皮纸颜色的范围 lower_brown np.array([10, 30, 30]) # 最小颜色值 upper_brown np.array([30, 255, 255]) # 最大颜色值 # 使用颜色范围进行颜色检测 mask cv2.inRange(hsv_image, lower_brown, upper_brown) # 计算掩码中白色像素检测到的颜色的数量 white_pixels np.sum(mask 255) # 计算图像的总像素数 total_pixels mask.shape[0] * mask.shape[1] # 计算特定颜色的占比 color_percentage (white_pixels / total_pixels) * 100 if color_percentage 20: # 20 # resul [] result2 ocr2.ocr(self.frame3, clsFalse) if result2 and not None in result2: for j in result2[0]: # print(san,j,are(j)) if j[1][1] 0.93 and process_string(j[1][0]): self.list_zong3.append(j) else: text3 except: text3 由于流水线实地第三步流程为将零件盒打包至棕色纸箱内。这里设定棕色纸箱面积大于画面整体的20%才会进行OCR检测。执行3次_performOCR3才执行w2set3。_performOCR3执行了不断从3个摄像头取帧显示在qt界面上ocr识别的操作。w2set3执行了对摄像头1的检测结果去重选出正确结果置信度0.93有正确文字是否警告的操作。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑