基于Opencv的缺陷检测任务

数据及代码见文末 

1.任务需求和环境配置

        任务需求:使用opencv检测出手套上的缺陷并且进行计数

 环境配置:pip install opencv-python

2.整体流程

        首先,我们需要定义几个参数。

  • 图像大小,原图像比较大,首先将图像resize一下再做后续处理
  • 图像阈值处理的相应阈值
  • 反转阈值的参数设置
  • 边缘检测的阈值
  • 轮廓设置及展示相关的字体颜色
################################
# --- Variables ---
################################
IMAGE_SIZE = (500, 500)

# -- Threshold Details --
# *THRESHOLD_VALUE:需要根据数据来实验一下
THRESHOLD_VALUE = 130
MAX_VALUE = 255

# -- Invert Threshold Details --
INV_THRESHOLD_VALUE = 50
INV_MAX_VALUE = 255

# -- Canny Details --
THRESHOLD1 = 100
THRESHOLD2 = 70

# --contour properties--
CON_COLOR = (0, 0, 255)
CON_THICKNESS = 1

# -- 字体颜色--
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
RED = (0, 0, 255)
STACK_IMG_SIZE = (200, 200)

整体流程如下:

  • 首先,读取图像,对图像进行resize并转化为灰度图
  • 然后进行图像阈值处理,经过图像阈值处理后,缺陷部分能够明显的区分出来,但是对于一些小的缺陷部分还不够明显
  • 因此,再对图像进行形态学处理,让这些小的缺陷部分凸显出来。
  • 在形态学操作后需要进行反转阈值,否则将无法检测到缺陷
  • 然后使用边缘检测并找到轮廓
  • 最后,完成展示 

        为什么要进行反转阈值?下面的不使用反转阈值的检测结果。在不反转阈值的情况下,边缘检测更加关注于白色的区域,因此无法检测到缺陷 

3.效果展示

        效果展示如下: 

        

 整体代码:

# 1:读数据
imageOri = cv2.imread(path)
#print(imageOri)

# 2:灰度图
image = cv2.cvtColor(imageOri,cv2.COLOR_BGR2GRAY)
#cv2.imshow('image_gray',image)
#cv2.waitKey(0)
#cv2.destroyAllWindows()

# 3:resize
imageOri = cv2.resize(imageOri,IMAGE_SIZE)
image = cv2.resize(image,IMAGE_SIZE)

# 4:THRESHOLD操作
ret,thresh_basic = cv2.threshold(image,THRESHOLD_VALUE,MAX_VALUE,cv2.THRESH_BINARY)

# 5:形态学操作
kernel = np.ones((3,3),np.uint8)
img_erosion = cv2.erode(thresh_basic,kernel,iterations=1)

ret, thresh_inv = cv2.threshold(img_erosion,INV_THRESHOLD_VALUE,INV_MAX_VALUE,cv2.THRESH_BINARY_INV)

# 6:Canny边缘检测
edged = cv2.Canny(img_erosion,THRESHOLD1,THRESHOLD2)

# 7:轮廓
contours,h = cv2.findContours(thresh_inv,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)


    # ++++++++++++++++++
    # -- Image Stack  --
    # ++++++++++++++++++
font = cv2.FONT_HERSHEY_SIMPLEX

imageRz = cv2.resize(image, STACK_IMG_SIZE)
thresh_basicRz = cv2.resize(thresh_basic, STACK_IMG_SIZE)
img_erosionRz = cv2.resize(img_erosion, STACK_IMG_SIZE)
thresh_invRz = cv2.resize(thresh_inv, STACK_IMG_SIZE)
edgedRz = cv2.resize(edged, STACK_IMG_SIZE)

imageRz = cv2.putText(imageRz, 'GrayScale', (5, 15), font, 0.5, WHITE, 1, cv2.LINE_AA)
thresh_basicRz = cv2.putText(thresh_basicRz, 'ThresholdBasic', (5, 15), font,
                             0.5, WHITE, 1,cv2.LINE_AA)
img_erosionRz = cv2.putText(img_erosionRz, 'Morphology-Erosion', (5, 15), font,
                            0.5, WHITE, 1, cv2.LINE_AA)
thresh_invRz = cv2.putText(thresh_invRz, 'Threshold-mode INV', (5, 15), font,
                           0.5, BLACK, 1, cv2.LINE_AA)
edgedRz = cv2.putText(edgedRz, 'Canny Edges', (5, 15), font, 0.5, WHITE, 1, cv2.LINE_AA)

numpy_horizontal_concat = np.concatenate((imageRz, thresh_basicRz, img_erosionRz,
                                          thresh_invRz, edgedRz), axis=1)

cv2.imshow('Filtering...', numpy_horizontal_concat)

# +++++++

# get total contours
num_of_con = str(len(contours) - 1)
print("Number of Contours found = " + num_of_con)
if len(contours) > 1:
    print('======================================')
    print('=       MARKINGS DETECTED            =')
    print('======================================\n\n')

# show original img
#cv2.imshow('Original Image', imageOri)
# draw contours on original img
if int(num_of_con) != 0:
    for i in range(int(num_of_con)):
        highlighted_img = cv2.drawContours(imageOri, contours, i, CON_COLOR, CON_THICKNESS)

    highlighted_img = cv2.putText(highlighted_img, 'Approximately {} defect(s) detected'.
                                  format(num_of_con), (5, 15),
                                  font, 0.5, GREEN, 1, cv2.LINE_AA)
else:
    highlighted_img = cv2.putText(imageOri, 'Unable to detect defects!',
                                  (5, 15), font, 0.5, RED, 2, cv2.LINE_AA)

# show markings highlighted img
cv2.imshow('Highlighted Defect', highlighted_img)
# save image containing highlighted defect
cv2.imwrite('Output Images/{}_DEFECTS_HIGHLIGHTED.jpg'.format(file.split('.')[0]), highlighted_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

数据及代码链接:

链接:https://pan.baidu.com/s/1_3w6plAgSebrJxeyxbJO2g?pwd=uyau 
提取码:uyau