【问题标题】:Separate/reposition/translate shapes in image with pillow in python用python中的枕头分离/重新定位/翻译图像中的形状
【发布时间】:2015-08-13 02:35:47
【问题描述】:

我需要用 python 分离或转换或替换图像中的像素,以便所有形状之间共享相同的距离和画布的限制。

背景为白色,形状为黑色。

重要提示:图像是动态的,所有图像都有不同位置的条,这意味着我需要检测条的开始位置和结束的位置以绘制最终图像!

这是一个示例输入图像

这是一个示例输出图像

我是手工做的,我不知道是否所有的条都间隔相同的距离,这只是一个例子。

生成的画布大小也可以改变,但理想情况下,我希望所有画布在重新定位条后都具有相同的宽度和高度。

图像中的所有像素都是黑色或白色,这应该会更容易。

到目前为止,我已经尝试过检测形状,但是当它们彼此太靠近时,无法正确检测到某些形状:

saut = 1
start_ab = 0
end_ab = 0
start_or = im2.size[1] - 1
end_or = 0
size = 0

shapes = []

for y in range(0, im2.size[0], saut):  # slice across
    for x in range(0, im2.size[1], 1):  # slice down
        pix = im2.getpixel((y, x))
        if pix != 255:
            start_or = min(start_or, x)
            end_or = max(end_or, x)
            inshape = True

    if foundshape == False and inshape == True:
        foundshape = True
        start_ab = y

    if foundshape == True and inshape == False:
        foundshape = False
        end_ab = y
        size = max(size, end_ab)
        shapes.append((start_ab, end_ab, start_or, end_or))
        start_or = im2.size[1] - 1
        end_or = 0
    inshape = False

print shapes
# example shapes output NOT FROM THE EXAMPLE IMAGES PROVIDED but from other shapes [(54, 171, 72, 233), (216, 324, 108, 251), (342, 486, 0, 215), (513, 765, 18, 260), (792, 918, 90, 242)]

而且还是要绘制新图像,我不知道该怎么做,而且有些图像的形状中带有“孔”,这使得“重绘”有点复杂。

【问题讨论】:

  • 您能否编辑您的代码以包含您正在进行的导入,以便我们重现您的问题?
  • @S4M 不,我不需要您重现我的问题,如果您回答的问题就足够了,另外,如果您需要图像,请使用示例中提供的图像
  • 通过阅读您的代码,您的形状似乎是由(start_ab, end_ab, start_or, end_or) 定义的,如果我理解得很好,它代表了矩形的坐标,所以我认为您也必须得到孔。我建议扫描点 (start_ab, start_or) 和 (end_ab,end_or)` 之间的所有坐标并列出那些为空的,因此您的形状将以(start_ab, end_ab, start_or, end_or,empty_points) 为特征,其中empty_points 将是一个点列表。
  • 是的,我知道 S4M,谢谢指出,问题是,这与这里的问题无关,你能回答这个问题吗?
  • 这是个问题吗:“而且还是要绘制新图像,我不知道该怎么做,而且有些图像的形状中带有“孔”,所以“重绘“稍微复杂一点。” ?在这种情况下,您只需要按照我的建议存储形状,然后浏览您拥有的数据,相应地移动横坐标并在像素不为空时填充像素。我可以为你写一些伪代码——它不会工作,因为我不知道你正在使用的库,但你应该能够调整它。

标签: python algorithm python-imaging-library image-manipulation pillow


【解决方案1】:

而且还是要绘制新图像,我不知道该怎么做,而且有些图像的形状中带有“孔”,这使得“重绘”有点复杂。

一旦你建立了一个矩形的边界,你可以使用 Image.crop() 函数从图像中提取一个矩形(包括那些孔)和 Image.paste() 将它们粘贴到正确的位置。本教程包含一个示例:

http://pillow.readthedocs.org/en/latest/handbook/tutorial.html#cutting-pasting-and-merging-images

【讨论】:

  • 不错的 Michiel,要试试看 :)
【解决方案2】:

计算每个形状之间距离的代码。它假定形状具有相同的宽度:

def calcDistanceBetweenShapes(nShapes, shapeWidth, totalWidth):
    totalBlank = totalWidth-nShapes*shapeWidth
    return totalBlank/nShapes

移动形状横坐标的代码(假设形状存储为(start_ab, end_ab, start_or, end_or,empty_points)):

def setNewAbscissa(shape, new_start_ab):
    start_ab, end_ab = shape[0], shape[1]
    shift = new_start_ab - start_ab
    new_end_ab = end_ab + shift
    new_empty_points = map(lambda pt: (pt[0]+shift,pt[1]),empty_points)
    return (new_start_ab, new_end_ab,start_or, end_or, new_empty_points)

现在让我们调用d 形状之间的距离。第一个形状不会移动,所以它的坐标保持不变。第二个形状的start_ab 将是previous_end_ab+d,其中previous_end_ab 是第一个形状的end_ab,依此类推。这提供了一种算法来计算所有形状的坐标。

def get_new_shapes(shapes, totalWidth):
    shift = calcDistanceBetweenShapes(len(shapes), shapes[0][1] - shape[0][0], totalWidth)
    res = [shapes[0]]
    previous_shape = shapes[0]
    for shape in shape[1:]:
         new_start_ab = previous_shape[1] + shift
         new_shape =  setNewAbscissa(previous_shape,new_start_ab)
         res.append(new_shape)
         previous_shape = new_shape

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-16
    相关资源
    最近更新 更多