OpenCV находит контуры коробки на основе 4 квадратных точек вокруг
Есть ли способ получить содержимое внутри поля (отмеченный пунктирным красным прямоугольником) на основе 4 маленьких квадратов вокруг него?
https://s tackru.com/images/9156bb969e075b159be849c3d456aacc6013ac3b.png
Мой код:
# Read and resize image
img_input = cv2.imread(args.pop('image'), )
img_input_height, img_input_width, _ = img_input.shape
img_input_ap = img_input_width / img_input_height
img_input_width = int(const_image_max_height * img_input_ap)
img_input = cv2.resize(img_input, (img_input_width, img_input_height,), )
# Process image color
img_final = img_input.copy()
img_gray = cv2.cvtColor(img_input, cv2.COLOR_BGR2GRAY, )
img_blur = cv2.GaussianBlur(img_gray, (5, 5,), 5)
img_canny = cv2.Canny(img_blur, 10, 70, )
# Find around contours
img_canny_contours, _ = cv2.findContours(
img_canny,
cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_NONE,
)
# Find square contours
img_preview = img_final.copy()
for contour in img_canny_contours:
rect = cv2.boundingRect(contour)
rect_width = rect[2]
rect_height = rect[3]
if 0.8 <= (rect_width / rect_height) <= 1.2:
# Now I founded the squares...
# Now I need to find the rectangle between 4 squares founded here...
cv2.imshow('img_preview', img_preview)
cv2.waitKey()
cv2.destroyAllWindows()
Текущий результат: https://s tackru.com/images/3cf01c3662ed8ebcda9f3afcc795ec9a2750fddb.jpg
1 ответ
В одном случае, учитывая, что пунктирная линия не поддерживается функциями рисования OpenCV.
Сначала прочтите изображение в оттенках серого, размытии и пороге:
blurred = cv2.GaussianBlur(im, (5, 5), 0)
threshold = 200
apply_val = 255
ret, th = cv2.threshold(blurred, threshold, apply_val, cv2.THRESH_BINARY)
Используйте функцию findContorus сcv2.RETR_CCOMP
как режим поиска:
contours, hierarchy = cv2.findContours(th, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
Восстановите вершину как центр контуров, пропуская первую, которая является границей изображения:
vertex = []
for c in contours[1:]:
moment = cv2.moments(c)
cx = int(moment["m10"] / moment["m00"])
cy = int(moment["m01"] / moment["m00"])
vertex.append((cx, cy))
Теперь вам нужно отсортировать вершину, вы можете определить метод, который это делает, это руководство:
sorted_vertex = [vertex[1], vertex[0], vertex[2], vertex[3]]
vertex_rotated = sorted_vertex[1:] + sorted_vertex[:1]
vertex_pairs = list(zip(sorted_vertex, vertex_rotated))
Вы можете нарисовать поли, используя sorted_vertex
или последовательность строк с использованием vertex_pairs
.
res = np.ones_like(im) * 255
res = cv2.cvtColor(res2, cv2.COLOR_GRAY2BGR)
for a, b in vertex_pairs:
cv2.line(res2, a, b, (0, 0, 255), 5)
Получение этого результата (посмотрите на SO, как нарисовать пунктирную линию):