Python 获取最大矩形的位置
我试着按照答案中的代码来做: 我很难理解如何找到算法找到的最大矩形的原点Python 获取最大矩形的位置,python,algorithm,Python,Algorithm,我试着按照答案中的代码来做: 我很难理解如何找到算法找到的最大矩形的原点(x,y) 收藏 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 pri
(x,y)
收藏
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)
import namedtuple
从操作员导入mul
将numpy作为np导入
导入功能工具
x=np.0(形状=(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
打印(x)
打印(最大尺寸(x))
Info=namedtuple('Info','start height')
def查找最大帧(mat,值=1):
“”“查找包含所有“值”的最大矩形的高度和宽度。”
it=国际热核实验堆(mat)
hist=[(el==值)表示下一个(it,[])中的el
最大大小,最大矩形大小(历史)
旧尺寸=(0,0)
坐标=无
对于y,枚举中的行(it):
hist=[(1+h)如果el==值,则h为0,zip中的el(hist,行)]
新矩形,c=最大矩形大小(历史)
最大尺寸=最大(最大尺寸,新尺寸,关键点=面积)
如果最大大小[0]*最大大小[1]>旧大小[0]*旧大小[1]:
坐标=[c[0],(y+2)-max_size[0]]
旧尺寸=最大尺寸
返回[最大大小,坐标]
def最大矩形大小(直方图):
“”“查找完全位于下方的最大矩形的高度和宽度。”
直方图。
"""
堆栈=[]
顶部=λ:堆栈[-1]
最大大小=(0,0)#最大矩形的高度和宽度
pos=0#直方图中的当前位置
对于位置,枚举中的高度(柱状图):
开始=位置#矩形开始的位置
尽管如此:
如果不是堆叠或高度>顶部()。高度:
stack.append(信息(开始、高度))#推送
打印(堆栈)
elif堆栈和高度<顶部()。高度:
max_size=max(max_size,(top().height,(pos-top().start)),
键=面积)
开始,u=stack.pop()
持续
break#height==top()。高度在这里
pos+=1
坐标=[0,0]
旧尺寸=(0,0)
对于开始,堆栈中的高度:
最大尺寸=最大(最大尺寸,(高度,(位置-开始)),键=面积)
如果最大大小[0]*最大大小[1]>旧大小[0]*旧大小[1]:
坐标=[起点,高度]
旧尺寸=最大尺寸
返回[最大大小,坐标]
def区域(大小):
返回functools.reduce(mul,大小)
在我的示例中,上面的代码似乎可以找到矩形的左上角,但当我在较大的图像上尝试时,它会崩溃,我无法调试原因。这里有一个解决方案修改了J.F.Sebastian的:
大小为(3,4)的矩形位于位置(2,1)。如果sum(max\u size)>sum(old\u max):行不正确,因为sum没有给出面积。你需要带上这个产品。要获得x坐标,您必须从
max\u rectangle\u size
@LawrenceWu返回它。是的,我实际上在本地更改了这个,但忘记编辑我的问题。即使是在一个简单的例子上,这似乎也不能正常工作。编辑了我的问题以包含示例。我尚未运行您的代码,但它似乎将返回矩形的底部(最大y坐标)。不是这样吗?@LawrenceWu刚刚更新了我的代码runnable@LawrenceWu当我在最初的while循环之后执行打印(堆栈)
时,我会一次又一次地重复这个[Info(start=0,height=0)]
是的,我分别得出了相同的确切结论。但是你得到了赏金:)我使用了Gist代码,因为这样看起来更安全,当完成时,我注意到你的代码很接近。:)顺便说一句,我快速查看了一下scipy.ndimage
或OpenCV
是否有此功能,但没有运气。使用(更多)本机代码解决此问题会带来很好的加速。。。
from collections import namedtuple
Info = namedtuple('Info', 'start height')
# returns height, width, and position of the top left corner of the largest
# rectangle with the given value in mat
def max_size(mat, value=0):
it = iter(mat)
hist = [(el==value) for el in next(it, [])]
max_size_start, start_row = max_rectangle_size(hist), 0
for i, row in enumerate(it):
hist = [(1+h) if el == value else 0 for h, el in zip(hist, row)]
mss = max_rectangle_size(hist)
if area(mss) > area(max_size_start):
max_size_start, start_row = mss, i+2-mss[0]
return max_size_start[:2], (start_row, max_size_start[2])
# returns height, width, and start column of the largest rectangle that
# fits entirely under the histogram
def max_rectangle_size(histogram):
stack = []
top = lambda: stack[-1]
max_size_start = (0, 0, 0) # height, width, start 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
elif stack and height < top().height:
max_size_start = max(
max_size_start,
(top().height, pos - top().start, top().start),
key=area)
start, _ = stack.pop()
continue
break # height == top().height goes here
pos += 1
for start, height in stack:
max_size_start = max(max_size_start, (height, pos - start, start),
key=area)
return max_size_start
def area(size): return size[0]*size[1]
self.assertEqual(max_size(self.__s2m("""
0 0 0 0 1 0
0 0 1 0 0 1
0 0 0 0 0 0
1 0 0 0 0 0
0 0 0 0 0 1
0 0 1 0 0 0""")), ((3, 4), (2, 1)))