【发布时间】:2020-12-01 21:56:45
【问题描述】:
首先,这是我尝试检测拉丝铝表面上的缺陷(平行线)的原始图像。
这是我采取的步骤:
- 高斯模糊
- 放大图像
- 将图像转换为灰度
- 变形关闭操作
- 再次扩张
- 图像差异
- Canny 边缘检测
- 寻找轮廓
- 在等高线周围画一条绿线
这是我的代码:
import numpy as np
import cv2
from matplotlib import pyplot as plt
import imutils
path = ''
path_output = ''
img_bgr = cv2.imread(path)
plt.imshow(img_bgr)
# bgr to rgb
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
plt.imshow(img_rgb)
# Converting to grayscale
img_just_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
# Displaying the grayscale image
plt.imshow(img_just_gray, cmap='gray')
# Gaussian Blur
ksize_w = 13
ksize_h = 13
img_first_gb = cv2.GaussianBlur(img_rgb, (ksize_w,ksize_h), 0, 0, cv2.BORDER_REPLICATE);
plt.imshow(img_first_gb)
# Dilate the image
dilated_img = cv2.dilate(img_first_gb, np.ones((11,11), np.uint8))
plt.imshow(dilated_img)
# Converting to grayscale
img_gray_operated = cv2.cvtColor(dilated_img, cv2.COLOR_BGR2GRAY)
# Displaying the grayscale image
plt.imshow(img_gray_operated, cmap='gray')
# closing:
kernel_closing = np.ones((7,7),np.uint8)
img_closing = cv2.morphologyEx(img_gray_operated, cv2.MORPH_CLOSE, kernel_closing)
plt.imshow(img_closing, cmap='gray')
# dilation:
# add pixels to the boundaries of objects in an image
kernel_dilation = np.ones((3,3),np.uint8)
img_dilation2 = cv2.dilate(img_closing, kernel_dilation, iterations = 1)
plt.imshow(img_dilation2, cmap='gray')
diff_img = 255 - cv2.absdiff(img_just_gray, img_dilation2)
plt.imshow(diff_img, cmap='gray')
# canny
edgesToFindImage = img_dilation2
v = np.median(img_just_gray)
#print(v)
sigma = 0.33
lower_thresh = int(max(0,(1.0-sigma)*v))
higher_thresh = int(min(255,(1.0+sigma)*v))
img_edges = cv2.Canny(edgesToFindImage, lower_thresh, higher_thresh)
plt.imshow(img_edges, cmap='gray')
kernel_dilation2 = np.ones((2,2),np.uint8)
img_dilation2 = cv2.dilate(img_edges, kernel_dilation, iterations = 2)
plt.imshow(img_dilation2, cmap='gray')
# find contours
contoursToFindImage = img_dilation2
(_, cnts, _) = cv2.findContours(contoursToFindImage.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
print(type(cnts))
print(len(cnts))
# -1 for all
cntsWhichOne = -1
# -1 for infill
# >0 for edge thickness
cntsInfillOrEdgeThickness = 3
img_drawing_contours_on_rgb_image = cv2.drawContours(img_rgb.copy(), cnts, cntsWhichOne, (0, 255, 0), cntsInfillOrEdgeThickness)
plt.imshow(img_drawing_contours_on_rgb_image)
这就是结果。
如何改进这种检测?有没有更有效的检测线的方法?
【问题讨论】:
-
您希望如何改进它?您对当前解决方案的哪些方面不满意?
-
@Trilarion 一直无法检测到线条。有没有办法从图像中破坏这个刷过的表面?如果是这样,我想我可以在图像差异部分使用它来改进线检测。