Detectar si una imagen tiene un borde, programáticamente (retorno booleano)

En primer lugar, he leído este post. ¿Cómo detectar un borde de imagen programáticamente? Sin embargo, parece estar haciendo una pregunta ligeramente diferente, sobre cómo encontrar las coordenadas X/Y.

Solo estoy tratando de encontrar si un sólido borde existe alrededor de una foto determinada. He explorado el uso de ImageMagick, pero ¿es esta la mejor opción? Nunca he hecho ninguna programación relacionada con la imagen, así que espero que haya una API simple que pueda resolver este problema. También soy bastante nuevo en cómo usar estas bibliotecas, por lo que se agradece cualquier consejo. Preferiría soluciones en Python o Java, aunque cualquier cosa está bien.

¡Gracias!

preguntado el 11 de junio de 12 a las 19:06

¿Qué tan diferente tiene que ser la frontera? 1 valor de matiz diferente, o por encima de algún delta? -

¿Sabes algo sobre el ancho del borde? -

@PhilH No estoy muy seguro de cómo responder esa pregunta en esos términos, lo siento. Diría que esta función debería detectar cualquier borde detectable por humanos (es decir, es bastante obvio para un humano cuando hay un borde alrededor de una imagen ). Además, las imágenes con las que estoy tratando generalmente serán imágenes de casas, paisajes, etc.

@SimeonVisser Los anchos de los bordes en las fotos con las que estoy trabajando pueden variar y variarán, por lo que no sabré nada sobre el ancho del borde antes de tiempo. -

3 Respuestas

Respondí una pregunta relacionada aquí, que elimina cualquier borde alrededor de una imagen, utiliza PIL. Puedes adaptar fácilmente el código para que regrese True or False pues haya borde o no, así:

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])

Sin embargo, esto volverá True incluso si solo un lado de la imagen tiene un borde. Pero parece que quiere saber si hay un borde alrededor de una imagen. Para hacer eso, cambie la última línea a:

    return all((bbox[0], bbox[1], (bbox[0] + bbox[2]) <= im.size[0], 
                                  (bbox[1] + bbox[3]) <= im.size[1]))

Esto solo devuelve verdadero si hay un borde en cada lado.

Por ejemplo:

False:

enter image description here

False:

enter image description here

True:

enter image description here

contestado el 23 de mayo de 17 a las 13:05

¡Gracias por tu ayuda! Eso casi funciona. Sin embargo, tengo problemas con su solución para encontrar si hay un borde alrededor (es decir, la línea 'devolver todo'). Lo probé en imágenes con bordes y obtuve 'Falso' cada vez. ¿Sabes por qué puede ser esto? ¿Podría darme algunos detalles sobre cómo funciona su respuesta? Sé que es mucho pedir, aunque te lo agradecería. ¡Gracias! - Conocido

@Ken - Si miras este enlace, Explico cómo funciona la sección principal del código. Tuve un error en la línea final que edité hace aproximadamente media hora, así que asegúrate de estar usando el código correcto. ¡Tal vez podrías publicar un enlace a una imagen para la que no funciona, y le echaré un vistazo! ;) - Fraxel

Ok genial gracias Tenía la versión correcta del código. Esta es la imagen con la que tengo problemas: imgur.com/qvZHX ¡Gracias! - Conocido

@Ken - arreglado, cambia el <para <= :) si miras de cerca, puedes ver que esa imagen tiene un borde más claro de un píxel en todo el contorno. Y la igualdad no estaba manejando este caso extremo correctamente. - Fraxel

¡Muchas gracias! Su respuesta fue muy útil para mí de muchas maneras. - Conocido

Después de ver la respuesta de fraxel, se me ocurre que, si no te importa el ancho del borde, puedes recortar el píxel más externo de cada lado y verificar que el color sea uniforme. Debe ser muy rápido; ajustando el color de fondo al del píxel en 0,0 y recortando 1,1 a w-2,h-2, la imagen restante debería tener exactamente 1 color.

Respondido el 11 de junio de 12 a las 22:06

entonces, el código correcto de la última línea debería ser:

 return all((bbox[0], bbox[1], bbox[2]) < im.size[0], bbox[3] < im.size[1]))

¿Correcto? para los dos últimos parámetros de la función getbbox(), son "la coordenada de píxel derecho e inferior del cuadro delimitador", no el ancho y el alto

Respondido 14 ago 19, 04:08

solo detecta si bbox es más pequeño que la imagen en todas las direcciones. (bbox[0], bbox[1]) es la esquina superior izquierda del cuadro delimitador y (bbox[2], bbox[3]) es la esquina inferior derecha, si están todos dentro de la imagen, hay debería ser una frontera - canción de halcón

¿Es posible hacerlo con image magic o Java? - por favor no me maten

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.