I'm trying to follow the code in the answer here: Find largest rectangle containing only zeros in an N×N binary matrix
I'm having difficulty understanding how to find the origin (x,y)
of the largest rectangle found by the algorithm.
from collections
import namedtuple
from operator import mul
import numpy as np
import functools
x = np.zeros(shape=(4,5))
x[0][0] = 1
x[0][1] = 1
x[0][2] = 1
x[0][3] = 1
x[1][0] = 1
x[1][1] = 1
x[1][2] = 1
x[1][3] = 1
print(x)
print(max_size(x))
Info = namedtuple('Info', 'start height')
def find_maximum_frame(mat, value=1):
"""Find height, width of the largest rectangle containing all `value`'s."""
it = iter(mat)
hist = [(el==value) for el in next(it, [])]
max_size, _ = max_rectangle_size(hist)
old_size = (0,0)
coordinates = None
for y,row in enumerate(it):
hist = [(1+h) if el == value else 0 for h, el in zip(hist, row)]
new_rect, c = max_rectangle_size(hist)
max_size = max(max_size, new_rect, key=area)
if max_size[0]*max_size[1] > old_size[0]*old_size[1]:
coordinates = [c[0], (y+2)-max_size[0]]
old_size = max_size
return [max_size, coordinates]
def max_rectangle_size(histogram):
"""Find height, width of the largest rectangle that fits entirely under
the histogram.
"""
stack = []
top = lambda: stack[-1]
max_size = (0, 0) # height, width of the largest rectangle
pos = 0 # current position in the histogram
for pos, height in enumerate(histogram):
start = pos # position where rectangle starts
while True:
if not stack or height > top().height:
stack.append(Info(start, height)) # push
print(stack)
elif stack and height < top().height:
max_size = max(max_size, (top().height, (pos - top().start)),
key=area)
start, _ = stack.pop()
continue
break # height == top().height goes here
pos += 1
coordinates = [0,0]
old_size = (0,0)
for start, height in stack:
max_size = max(max_size, (height, (pos - start)), key=area)
if max_size[0]*max_size[1] > old_size[0]*old_size[1]:
coordinates = [start,height]
old_size = max_size
return [max_size, coordinates]
def area(size):
return functools.reduce(mul, size)
The above code seems to work to in my example to find the upper left-hand corner of the rectangle, but when I try it on a larger image it's breaking down and I can't debug why.