以编程方式检测图像是不是有边框(返回布尔值)
Posted
技术标签:
【中文标题】以编程方式检测图像是不是有边框(返回布尔值)【英文标题】:Detect if an image has a border, programmatically (return boolean)以编程方式检测图像是否有边框(返回布尔值) 【发布时间】:2012-06-11 18:27:20 【问题描述】:首先,我已经阅读了这篇文章。 How to detect an image border programmatically? 不过,他似乎在问一个稍微不同的问题,即找到 X/Y 坐标。
我只是想找出给定照片周围是否存在 实心 边框。 我已经使用 ImageMagick 进行了探索,但这是最好的选择吗? 我从来没有做过任何与图像相关的编程,所以我希望只有一个简单的 api 可以解决这个问题。 我对如何使用这些库也很陌生,所以任何建议都值得赞赏。 我更喜欢 Python 或 Java 的解决方案,不过什么都可以。
谢谢!
【问题讨论】:
边界必须有多大不同? 1 个色调值不同,或高于某个增量? 你知道边框的宽度吗? @PhilH 我不太确定如何用这些术语回答这个问题抱歉 - 我会说这个功能应该检测到任何人类可检测的边界(IE。这对人类来说相当明显当图片周围有边框时)。另外,我处理的图片一般是房屋、风景等的图片。 @SimeonVisser 我正在使用的照片中的边框宽度可以并且会有所不同,所以我不会提前知道边框的宽度。 【参考方案1】:我回答了一个相关问题here,它删除了图像周围的任何边框,它使用PIL。您可以轻松修改代码,使其返回True
或False
是否有边框,如下所示:
from PIL import Image, ImageChops
def is_there_a_border(im):
bg = Image.new(im.mode, im.size, im.getpixel((0,0)))
diff = ImageChops.difference(im, bg)
diff = ImageChops.add(diff, diff, 2.0, -100)
bbox = diff.getbbox()
return bbox != (0,0,im.size[0],im.size[1])
但是,即使图像只有一侧有边框,这也会返回 True
。但听起来你想知道图像周围是否有边框。为此,将最后一行更改为:
return all((bbox[0], bbox[1], (bbox[0] + bbox[2]) <= im.size[0],
(bbox[1] + bbox[3]) <= im.size[1]))
只有在每一边都有边框时才会返回 true。
例如:
False:
False:
True:
【讨论】:
感谢您的帮助!这只是工作。但是,我在查找是否有边界的解决方案时遇到了问题(即“全部返回”行)。我已经在带边框的图片上尝试过,每次都得到“错误”。你知道为什么会这样吗?你能给我一些关于你的答案是如何工作的细节吗?我知道这要求很多——不过我会很感激的。谢谢! @Ken - 如果您查看this link,我会解释代码的主要部分是如何工作的。我在大约半小时前编辑的最后一行出现了错误,因此请确保您使用的是正确的代码。也许你可以发布一个链接到它不工作的图像,我会看看它! ;) 好的,非常感谢。我确实有正确版本的代码。这是我遇到问题的图像:imgur.com/qvZHX 谢谢! @Ken - 已修复,将<
s 更改为 <=
:) 如果您仔细观察,您会发现该图像的边框一直亮了一个像素。并且等式没有正确处理这种极端情况。
非常感谢!你的回答在很多方面对我很有帮助。【参考方案2】:
看到 fraxel 的回答后,我突然想到,如果您不在乎边框有多宽,您可以裁剪出每边的最外层像素并检查颜色是否均匀。应该很快;通过将背景颜色设置为 0,0 像素的颜色,并将 1,1 裁剪为 w-2,h-2,剩余的图像应该只有 1 种颜色。
【讨论】:
【参考方案3】:所以,最后一行的正确代码应该是:
return all((bbox[0], bbox[1], bbox[2]) < im.size[0], bbox[3] < im.size[1]))
对吗? getbbox() 函数的最后两个参数是“边界框的右下像素坐标”,而不是宽度和高度
【讨论】:
它只是检测bbox是否在各个方向上都小于图像。 (bbox[0], bbox[1]) 是边界框的左上角, (bbox[2], bbox[3]) 是右下角,如果它们都在图像内部,则应该是边框 有没有可能用image magic或Java来做?以上是关于以编程方式检测图像是不是有边框(返回布尔值)的主要内容,如果未能解决你的问题,请参考以下文章