600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > Python+Opencv的工业级机器视觉检测系统

Python+Opencv的工业级机器视觉检测系统

时间:2019-10-23 23:38:40

相关推荐

Python+Opencv的工业级机器视觉检测系统

目录

前言

一、系统介绍

1.1 设计目的

1.2 硬件配置

二、程序描述

2.1 视觉检测流程

2.2 程序描述

2.2.1 清空文件夹模块

2.2.2ROI区域划分模块

2.2.3黑白占比计算

2.2.4图像处理模块

三、系统简易展示

3.1 合格展示

3.2 不合格展示

四、系统框架代码

前言

1. 由于受到软件著作权保护,本视觉检测系统仅提供部分算法设计思路。该系统建议作为一个框架使用,通过调整算法结构,具体参数和文件路径实现视觉检测。

2. 完整版本已投入工业现场使用。

一、系统介绍

1.1 设计目的

本系统主要针对PCB进行检测,PCB在焊锡过程中可能出现以下问题:

- (1)焊点缺失

- (2)焊点粘连

因此提出以下要求:

- (1)对PCB上的焊点进行检测

- (2)对所有焊点进行判断是否存在缺陷,有缺陷则报警,无缺陷则显示合格

- (3)将视觉检测系统与PLC进行通讯,通过三色灯显示检测结果

1.2 硬件配置

二、程序描述

2.1 视觉检测流程

检测思路:

当系统启动时,首先判断寄存文件夹的文件数量,当文件数量不为1时,删除除了最新图片外的所有图片,然后进行图片读取。当文件数量为1时直接进行图片读取。在读取到图片后对图片通过掩膜进行裁剪,然后进行图像处理,消除图片噪声,提取有用的特征。用黑白像素的占比计算来作为合格条件进行判断,当白像素超出阈值时为不合格,通过与PLC通讯使得三色灯亮,低于阈值时三色灯绿灯亮,最终显示OK/NG结果,系统结束。

2.2 程序描述

2.2.1 清空文件夹模块

模块介绍:

1.通过python内置的os库来进行文件读取,获得目标文件夹长度list,通过len(list)计算文件夹长度。

2.当目标文件夹长度不为1时,显示长度(文件夹内图片数量),通过for循环递增文件夹长度的倒数第二个位置,用os.Remove()将图片删除,剩下最后一张即最新的图片。

3.当目标文件夹长度为1时,说明相机驱动软件MVS采集到最新图片,直接pass进入下一模块。

2.2.2ROI区域划分模块

模块介绍:

1.图片在计算机中以数组形式显示,相机分辨率为1280*1024,受限于焦距和光圈限制,不能完全覆盖PCB大小,因此需要把1280*1024的原图裁剪成和PCB大小相同的300*350的图片。PCB板的焊锡分布为上面五个,中间三个,下面三个,生成目标区域的掩膜mask,并且将掩膜像素全置为255,三个mask区域大小分别为:

2.通过位操作cv.bitwise_and将图像和掩膜进行合并,分别提取出三个目标区域,最后通多cv.add()将区域相加,使得原本图像只剩下三个目标区域:

2.2.3黑白占比计算

模块介绍:

用black-pixel和white-pixel两个变量储存黑白像素点的数量,通过遍历1280*1024即13,107,200个像素,使用PLI包内的Image模块,image.size()用于读取PIL方式image.open()打开的图片,该模式下读取图片的宽和长,将值返回到width和height两个变量中。通过image.getpixel()获取某点处像素,统计图片画幅中的像素点数量,当遍历完所有像素后,计算黑白占比并显示,流程结束。

2.2.4图像处理模块

图像处理模块是一个线性流程,其中的图像处理算法为灰度处理 - 形态学处理(腐蚀 - 膨胀 - 开运算)- 高斯滤波 - 轮廓提取,分别使用到以下函数:

表2 — 图像处理函数表

具体函数的使用如下:

三、系统简易展示

处理前图片为PCB板,因涉及专利设计保护,因此使用SW模型代替。

3.1 合格展示

图1 处理前图片 图2处理后图片

图3 检测结果显示

3.2 不合格展示

图4 处理前图片图5处理后图片

图6 处理前图片

四、系统框架代码

import osimport timeimport cv2 as cvimport numpy as npfrom PIL import Imagefrom appdirs import unicode'''算法设计:(1)形态学处理 -- 1、(腐蚀5*5,膨胀3*3,开运算7*7,均为矩形结构元) 2、高斯滤波(2)blob筛选 -- 提取并绘制轮廓,减少图片噪声''''''检测流程:(1)从文件夹内读取RGB图片(2)对RGB图片进行灰度处理,形态学处理,高斯滤波和轮廓提取,其中灰度处理后需要进行掩膜处理,提取目标区域.(3)对处理完的图片进行黑白占比计算,焊锡点缺失会导致焊锡处反光,导致亮度过高.当白色占比超过阈值,判断为焊锡缺失(4)输出合格与不合格后,与PLC通过modbus通讯'''def cut(cut):'''主要功能:把 1024*1280 的原图 裁剪成 PCB大小的 300*350 的图片然后将三个焊锡区域提取出来并合并'''img = cut[350:650, 500:850] # 把 1280*1024 的原图 裁剪成 PCB大小的 300*350 的图片# 分割区域1 -- 上面五个焊锡点mask1 = np.zeros(img.shape[:2], np.uint8)mask1[10:60, 10:330] = 255mask1_img = cv.bitwise_and(img, img, mask=mask1)# cv.imshow('mask1',mask1_img)# 分割区域2 -- 中间三个焊锡点mask2 = np.zeros(img.shape[:2], np.uint8)mask2[80:130, 70:270] = 255mask2_img = cv.bitwise_and(img, img, mask=mask2)# cv.imshow('mask2',mask2_img)# 分割区域3 -- 下面三个焊锡点mask3 = np.zeros(img.shape[:2], np.uint8)mask3[240:290, 70:270] = 255mask3_img = cv.bitwise_and(img, img, mask=mask3)# cv.imshow('mask3',mask3_img)pic1 = cv.add(mask1_img, mask2_img) # 区域1+区域2pic = cv.add(pic1, mask3_img) # 区域(1+2)+区域3return picdef remove():'''主要功能:保证文件夹内只有最新的那一张图片'''# 时间在0.01以内,因此不记录时间path = r'C:\Users\-libr\Desktop\PCB\PCB input_dir'file = unicode(path)files = os.listdir(file) # 创建由文件名组成的列表#print('filelist:', files)if len(os.listdir(path)) > 1:print(f"图片数量为:{len(os.listdir(path))}")for i in range(len(os.listdir(path))-1):#设置 len(os.listdir(path))-1 是为了保证i递增到倒数第二,留下最新的图片i += 1#print(i)os.remove(os.path.join(path, f'PCB{i}.jpg'))elif len(os.listdir(path)) == 1:print(f"图片数量为:1 ")#文件夹内只有最新的那张图片passdef count(image):'''主要功能;输入单张图片图片,计算并输出'黑白占比的计算结果'和'计算一次的时间''''start = time.time()white_pixel = 0black_pixel = 0width, height = image.sizefor i in range(width):for j in range(height):if image.getpixel((i,j)):white_pixel += 1else:black_pixel += 1black = black_pixel / (width * height)white = white_pixel / (width * height)end = time.time()cost = end - startprint('黑白检测时间:%s'%cost)print('黑色占比:%s\n白色占比:%s'%(black,white))#判断黑白占比阈值,输出检验结果if black > 0.99:return(print('合格\n'))else:return(print('不合格\n'))def convert(input_dir, output_dir):for filename in os.listdir(input_dir):'''主要功能:读取文件夹内的图片,进行图像处理后,并将其保存到指定文件'''path = input_dir + "/" + filename # 获取文件路径gray_img = cv.imread(path, 0) # 读取图片,参数0为直接以灰度模式读取cut_pic = cut(gray_img) #提取三个焊锡区域后的图片# 腐蚀kernel1 = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))img_erode = cv.erode(cut_pic, kernel1)# 膨胀kernel2 = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))img_dilate = cv.dilate(img_erode, kernel2)# 开运算kernel3 = cv.getStructuringElement(cv.MORPH_RECT, (7, 7))img_open = cv.morphologyEx(img_dilate, cv.MORPH_OPEN, kernel3, iterations=1)# 高斯滤波img_gaussian = cv.GaussianBlur(img_open, (1, 1), 2)# 二值化ret, img_turn = cv.threshold(img_gaussian, 127, 255, 0)# 发现轮廓contours, heriachy = cv.findContours(img_turn, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)for i, contour in enumerate(contours):# 绘制每条轮廓cv.drawContours(img_turn, contours, i, (0, 0, 255), 2)cv.imwrite(output_dir + '/' + filename, img_turn)cv.imshow("PCB", img_turn)cv.waitKey()cv.destroyAllWindows()# cv.destroyAllWindows(1)def read_path(output_dir):for filename in os.listdir(output_dir):'''主要功能:定义读取路径的函数,为用PIL打开图片获得'''path = output_dir + "/" + filename # 获取文件路径image = Image.open(path).convert('L')count(image)if __name__ == '__main__':# 输入RGB图片input_dir = r'C:\Users\-libr\Desktop\PCB\PCB input_dir' # 输入文件夹output_dir = r'C:\Users\-libr\Desktop\PCB\PCB output_dir' # 输出文件夹#1、保持文件夹内只有最新图片remove()#2、对图片进行读取,处理和保存convert(input_dir, output_dir)#3、对图片进行黑白占比计算并判断read_path(r'C:\Users\-libr\Desktop\PCB\PCB output_dir')

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。