最小化图像区域,同时保留特定指标

时间:2015-11-14 17:19:05

标签: python image-processing scipy mathematical-optimization integer-programming

我有一张照片,我希望找到最小面积的作物,同时保留一定比例的边缘能量。

我对此的看法是将其表述为优化问题,并让scipy的约束优化器解决它[代码见下文]。 这显然是有问题的,因为它是integer problem(裁剪采用左上角和右下角的整数坐标作为参数)。实际上fmin_cobyla在运行20秒后无法找到解决方案,而fmin_slsqp在使用“ LSQ子问题中的奇异矩阵C(退出模式6)”进行一次迭代后失败。 / p>

关于如何解决这个问题的任何想法呢?是否有偶然的库来处理图像上的优化问题?

from skimage.filters import sobel
from PIL import Image
from scipy.optimize import fmin_slsqp

def objective(x):
    # minimize the area
    return abs((x[2] - x[0]) * (x[3] - x[1]))

def create_ratio_constr(img):
    def constr(x):
        # 81% of the image energy should be contained
        x = tuple(map(int, x))
        crop = img.crop((x[0], x[1], x[2], x[3]))
        area_ratio = round(sum(list(crop.getdata())) /
                           float(sum(list(img.getdata()))), 2)
        if area_ratio == 0.81:
            return 0.0
        return -1
    return constr

def borders_constr(x):
    x = tuple(map(int, x))
    # 1st point is up and left of 2nd point
    rectangle = x[0] < x[2] and x[1] < x[3]

    # only positive values valid
    positive = x[0] > 0 and x[1] > 0

    if rectangle and positive:
        return 0.0
    return -1

img = Image.open("/some/path.jpg")
# get the edges
edges = Image.fromarray(sobel(img.convert("L")))

ratio_constr = create_ratio_constr(edges)
x = fmin_slsqp(objective,
               (0, 0, edges.size[0]-1, edges.size[1]-1),
               [borders_constr, ratio_constr],
               disp=1)

print x

1 个答案:

答案 0 :(得分:0)

我可能会忽略裁剪区域角落的整数要求并解决松弛问题。然后考虑将裁剪边缘移入或移出最近的整个像素。如果是出于美学目的,+ / - 部分像素可能无关紧要。如果它必须是正确的,那么在两个地方只考虑四个边缘,所以不应该找到最好的16个选择中的一个。