Выше находится исходное изображение, которое мне нужно для обнаружения дефектов. Дефектами являются неправильные отверстия на средней линии запечатывания. Я закончил большую часть работы, применив порог, морфологию и проекцию оси X, чтобы удалить отражающие области. При работе с областями отражения, убедившись, что незначительные дефекты в областях отражения незначительны, я понял, что существует и крайний случай — большие дефекты в областях отражения. Непростительно, если я пропущу крупные дефекты, хотя они находятся в области отражения.
Ребята, есть идеи, как это решить?
import os
import time
import cv2
import numpy as np
import plt
def overlap_with_reflection(x, w, reflect_ranges):
# Expand the reflection, 100 maybe too aggressive
rect_l = x - 100
rect_r = x + w + 100
for rl, rr in reflect_ranges:
# Discard areas where defective regions crossing with reflective regions
if not (rect_r < rl or rect_l > rr):
return True
return False
measure_path = r"E:\visual_relative_images\inspection\test"
for filename in os.listdir(measure_path):
if not filename.lower().endswith(('.bmp', '.png', '.jpg', '.jpeg', '.tif')):
continue
start_time = time.time()
measure_path_pic = os.path.join(measure_path, filename)
file_name = os.path.basename(measure_path_pic)
name, ext = os.path.splitext(file_name)
measure = cv2.imread(measure_path_pic)
if measure is None:
continue
# Brighter
alpha = 1.0
beta = 40
measure = cv2.convertScaleAbs(measure, alpha=alpha, beta=beta)
cv2.imwrite(f"lightened_{filename}", measure)
vis = measure.copy()
gray_raw = cv2.cvtColor(measure, cv2.COLOR_BGR2GRAY)
# Corp the top and bottom area
h_image, w_image = gray_raw.shape
vis = vis[int(0.39 * h_image):int(0.57 * h_image), :]
roi = gray_raw[int(0.39 * h_image):int(0.57 * h_image), :]
# Threshold segmentation
_, binary = cv2.threshold(roi, 118, 255, cv2.THRESH_BINARY)
# Find the biggest area
contours, hierarchy = cv2.findContours(binary, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
max_contour = max(contours, key=cv2.contourArea)
# Get the biggest area image
mask = np.zeros(binary.shape, dtype=np.uint8)
cv2.drawContours(mask, [max_contour], -1, 255, thickness=cv2.FILLED)
max_image = cv2.bitwise_and(binary, binary, mask=mask)
# Morphology
kernel_link = cv2.getStructuringElement(cv2.MORPH_DILATE, (7, 3))
test_image = cv2.morphologyEx(max_image, cv2.MORPH_CLOSE, kernel_link, iterations=2)
cv2.imwrite(f"processed_{filename}", test_image)
# X-axis area projection (glare removal)
x_projection = np.sum(test_image == 255, axis=0)
x = np.arange(len(x_projection))
plt.figure(figsize=(10, 4))
plt.plot(x, x_projection, linewidth=1)
plt.xlabel("X (image column)")
plt.ylabel("White pixel area")
plt.title("Horizontal Projection")
plt.savefig(f'Horizontal_Projection_{name}.png')
# The threshold for reflective areas is defined as the y-axis value above which the corresponding x-axis coordinates are classified as reflective regions
threshold = 78
valid_x = np.where(x_projection > threshold)[0]
# Merge reflective columns into contiguous intervals
reflect_ranges = []
if len(valid_x) > 0:
start = valid_x[0]
prev = valid_x[0]
for v in valid_x[1:]:
if v == prev + 1:
prev = v
else:
reflect_ranges.append((start, prev))
start = v
prev = v
reflect_ranges.append((start, prev))
# Obtain the first sub-contour within this maximum contour through the RETR_CCOMP hierarchy
contours_f, hierarchy_f = cv2.findContours(test_image, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
hierarchy_f = hierarchy_f[0]
max_area = 0
max_idx = -1
# Find the position of the largest white contour max_idx (parent contour) by checking hierarchy_f[i][3] == -1
for i, cnt in enumerate(contours_f):
area = cv2.contourArea(cnt)
if area > max_area and hierarchy_f[i][3] == -1:
max_area = area
max_idx = i
for i, cnt in enumerate(contours_f):
# Determine whether its parent contour is the one just identified
if hierarchy_f[i][3] == max_idx:
x, y, w, h = cv2.boundingRect(cnt)
if w * h < 90:
continue
if overlap_with_reflection(x, w, reflect_ranges):
continue
cv2.rectangle(vis, (x, y), (x + w, y + h), (0, 0, 255), 2)
end_time = time.time()
diff_time = end_time - start_time
print(diff_time)
cv2.imwrite(f"result_{filename}", vis)
Выше находится исходное изображение, которое мне нужно для обнаружения дефектов. Дефектами являются неправильные отверстия на средней линии запечатывания. Я закончил большую часть работы, применив порог, морфологию и проекцию оси X, чтобы удалить отражающие области. При работе с областями отражения, убедившись, что незначительные дефекты в областях отражения незначительны, я понял, что существует и крайний случай — большие дефекты в областях отражения. Непростительно, если я пропущу крупные дефекты, хотя они находятся в области отражения. Ребята, есть идеи, как это решить? [code]import os import time import cv2 import numpy as np import plt
def overlap_with_reflection(x, w, reflect_ranges): # Expand the reflection, 100 maybe too aggressive rect_l = x - 100 rect_r = x + w + 100
for rl, rr in reflect_ranges: # Discard areas where defective regions crossing with reflective regions if not (rect_r < rl or rect_l > rr): return True return False
measure_path = r"E:\visual_relative_images\inspection\test" for filename in os.listdir(measure_path): if not filename.lower().endswith(('.bmp', '.png', '.jpg', '.jpeg', '.tif')): continue
# Corp the top and bottom area h_image, w_image = gray_raw.shape vis = vis[int(0.39 * h_image):int(0.57 * h_image), :] roi = gray_raw[int(0.39 * h_image):int(0.57 * h_image), :]
# The threshold for reflective areas is defined as the y-axis value above which the corresponding x-axis coordinates are classified as reflective regions threshold = 78 valid_x = np.where(x_projection > threshold)[0]
# Merge reflective columns into contiguous intervals reflect_ranges = [] if len(valid_x) > 0: start = valid_x[0] prev = valid_x[0]
for v in valid_x[1:]: if v == prev + 1: prev = v else: reflect_ranges.append((start, prev)) start = v prev = v reflect_ranges.append((start, prev))
# Obtain the first sub-contour within this maximum contour through the RETR_CCOMP hierarchy contours_f, hierarchy_f = cv2.findContours(test_image, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE) hierarchy_f = hierarchy_f[0]
max_area = 0 max_idx = -1 # Find the position of the largest white contour max_idx (parent contour) by checking hierarchy_f[i][3] == -1 for i, cnt in enumerate(contours_f): area = cv2.contourArea(cnt) if area > max_area and hierarchy_f[i][3] == -1: max_area = area max_idx = i
for i, cnt in enumerate(contours_f): # Determine whether its parent contour is the one just identified if hierarchy_f[i][3] == max_idx: x, y, w, h = cv2.boundingRect(cnt)
if w * h < 90: continue
if overlap_with_reflection(x, w, reflect_ranges): continue