以编程方式检测图像是不是有边框(返回布尔值)

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。您可以轻松修改代码,使其返回TrueFalse 是否有边框,如下所示:

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 - 已修复,将 &lt;s 更改为 &lt;= :) 如果您仔细观察,您会发现该图像的边框一直亮了一个像素。并且等式没有正确处理这种极端情况。 非常感谢!你的回答在很多方面对我很有帮助。【参考方案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来做?

以上是关于以编程方式检测图像是不是有边框(返回布尔值)的主要内容,如果未能解决你的问题,请参考以下文章

快速使用 FMDB - 返回布尔值

是否可以使用布尔值而不是列表以这种方式进行洗牌?

一种返回布尔值的方法,该布尔值标识两个数组的值是不是相同

判断一个对象上是不是包含 一个属性的几种方法

Python:如何检查列表是不是包含数值并返回布尔值?

返回布尔值和消息的Pythonic方式[重复]