I have an image, which I've found and drawn the contours from opencv (see left image).
I'd like to draw a box (something like the one on the right) as follows which should be in contact with the most amount of points from the contour.
What functions would be useful here? I thought about trying to find the largest rectangle but as you can see there are areas that sit inside the region so it would exclude that?
Many thanks for your help!
First you need to transform the image into binary (black or white pixels) to differentiate between contour and the rest of the image (in the example the contour is white on a black background). Then you can "line-scan" the image, meaning to count the number of white pixel every row and every column. First horizontal edge (horizontal line with the most white pixels) of the rectangle should be in the first half of height of the image and the next horizontal edge in the second half. Like-wise for vertical edge (vertical line with the most white pixels), the first one should be in the first half of width of the image and the next one in the next. Go through the code below and it will become clear.
Example code:
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()
Result:
Input image: