# coding=utf-8 import cv2 import numpy as np import math # 修改图像的对比度,coefficent>0, <1降低对比度,>1提升对比度 建议0-2 def change_contrast(img, coefficent): imggray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) m = cv2.mean(img)[0] graynew = m + coefficent * (imggray - m) img1 = np.zeros(img.shape, np.float32) k = np.divide(graynew, imggray, out=np.zeros_like(graynew), where=imggray != 0) img1[:, :, 0] = img[:, :, 0] * k img1[:, :, 1] = img[:, :, 1] * k img1[:, :, 2] = img[:, :, 2] * k img1[img1 > 255] = 255 img1[img1 < 0] = 0 return img1.astype(np.uint8) # 修改图像的亮度,brightness取值0~2 <1表示变暗 >1表示变亮 def change_brightness(img, brightness): [averB, averG, averR] = np.array(cv2.mean(img))[:-1] / 3 k = np.ones((img.shape)) k[:, :, 0] *= averB k[:, :, 1] *= averG k[:, :, 2] *= averR img = img + (brightness - 1) * k img[img > 255] = 255 img[img < 0] = 0 return img.astype(np.uint8) # 对图像二值化并取中值滤波 def threshold_img(image): gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) retval, dst = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU) img_median = cv2.medianBlur(dst, 3) return img_median # 腐蚀图像 def corrosion_img(image): # 腐蚀操作会把裂痕也消除 kernel = np.ones((9, 9), dtype=np.uint8) opening = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel, 1) return opening # 找出最右侧的近似竖直直线 通过直线与水平的角度判断是否倾斜 大于容错率的竖直 小于容错率的倾斜 def lines_img(image): slopes = [] yErrorRange = 3 xErrorRange = 3 minLength = 20 # 创建一个LSD对象 lsd = cv2.createLineSegmentDetector(0) # 执行检测结果 dlines = lsd.detect(image) # 绘制检测结果 for dline in dlines[0]: x0 = int(round(dline[0][0])) y0 = int(round(dline[0][1])) x1 = int(round(dline[0][2])) y1 = int(round(dline[0][3])) length = math.hypot(x1 - x0, y1 - y0) if (x0 > 605 and x1 > 605): # print((x0, y0), (x1, y1)) # 需要根据角坐标排除 横向线,针对纵向线判断是否有倾斜 # 过滤横线 if not (abs(x1 - x0) > xErrorRange and abs(y1 - y0) < yErrorRange): # 过滤线段长度 if not (length < minLength): if x1 - x0 != 0: k = abs(y1 - y0) / abs(x1 - x0) angle = math.atan(k) * 180 / math.pi slopes.append(angle) print(angle) # cv2.line(img0, (x0, y0), (x1,y1), (0,255,0), 1, cv2.LINE_AA) # 有小于85度的就证明胶带倾斜了 threshold = 85 res = any(x < threshold for x in slopes) if res: print("胶带倾斜") else: print("胶带正确") def detectionImg(): # 读取输入图片 img = cv2.imread("img/a.png") l = 0 c = 34 # 亮度 -1~1 imgBrightness = change_brightness(img, float(l - 50) / float(50)) # 对比度 0~2 img0 = change_contrast(imgBrightness, c / 50) thresholdImg = threshold_img(img0) corrosionImg = corrosion_img(thresholdImg) lines_img(corrosionImg) # 显示并保存结果 cv2.imshow("gray", corrosionImg) cv2.imshow("lines", img0) cv2.waitKey(0) cv2.destroyAllWindows() if __name__ == '__main__': detectionImg()