与轮廓中最多点接触的最大正方形

Largest square in contact with most points in contour

我有一张图片,我从 opencv 找到并绘制了轮廓(见左图)。

我想画一个盒子(像右边那个)如下,它应该与轮廓中最多的点接触。

这里有什么功能有用?我想尝试找到最大的矩形,但如您所见,该区域内部有一些区域,因此它会排除该区域?

非常感谢您的帮助!

首先,您需要将图像转换为二进制(黑色或白色像素)以区分轮廓和图像的其余部分(在示例中,轮廓是黑色背景上的白色)。然后你可以“行扫描”图像,意思是计算每一行和每一列的白色像素的数量。矩形的第一个水平边缘(具有最多白色像素的水平线)应位于图像高度的前半部分,下一个水平边缘应位于图像高度的后半部分。同样对于垂直边缘(具有最多白色像素的垂直线),第一个应该在图像宽度的前半部分,下一个在下一个。看一下下面的代码就清楚了。

示例代码:

import cv2
import numpy as np

img = cv2.imread("2.png")
h, w = img.shape[:2]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU+cv2.THRESH_BINARY_INV)[1]
thresh = cv2.rectangle(thresh, (0, 0), (w, h), (0, 0, 0), 3)

width = 1
horizontal_line = []

best_hor_one = 0
best_hor_two = 0
count_hor_one = 0
count_hor_two = 0
for y in range(h):
    area = thresh[y:y+width, 0:h]
    try:
        line = cv2.countNonZero(area)
        if line >= count_hor_one and y < h//2:
            best_hor_one = y
            count_hor_one = line
        if line >= count_hor_two and y >= h//2:
            best_hor_two = y
            count_hor_two = line
    except TypeError:
        pass

best_ver_one = 0
best_ver_two = 0
count_ver_one = 0
count_ver_two = 0
for x in range(w):
    area = thresh[0:h, x:x+width]
    try:
        line = cv2.countNonZero(area)
        if line > count_ver_one and x < w//2:
            best_ver_one = x
            count_ver_one = line
        if line > count_ver_two and x >= w//2:
            best_ver_two = x
            count_ver_two = line
    except TypeError:
        pass

cv2.line(img, (best_ver_one, best_hor_one),
        (best_ver_two, best_hor_one), (0, 255, 0), 3)
cv2.line(img, (best_ver_one, best_hor_two),
        (best_ver_two, best_hor_two), (0, 255, 0), 3)
cv2.line(img, (best_ver_one, best_hor_one),
        (best_ver_one, best_hor_two), (0, 255, 0), 3)
cv2.line(img, (best_ver_two, best_hor_one),
        (best_ver_two, best_hor_two), (0, 255, 0), 3)

cv2.imwrite("res.png", img)
cv2.imshow("img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果:

输入图像: