Obtener valor pixeles de una imagen

2,665 views
Skip to first unread message

Paquillo Dubois

unread,
Mar 23, 2009, 10:37:37 AM3/23/09
to Software libre - Universidad de Granada
Hola.

No sé si este es el mejor sitio para hacer esta pregunta, pero llevo
unos días intentando resolver un problema y no lo consigo.

Necesito conocer el valor numérico de determinados pixeles de una
fotografía con objeto de realizar un cálculo con ellos uno a uno para
sumar todos los resultados y obtener un valor numérico que conparo con
distintas fotografías.

El planteamiento del problema es simple: no he conseguido obtener
estos valores.

He estado buscando si había un plugin para imageJ, pero no lo he
encontrado.

También he visto que hay un módulo en python (estoy haciendo el
programa en python): getpython (http://snippets.dzone.com/posts/show/
632), pero no he conseguido correr ningún programa que lo use.

También he visto una clase en Java (pixelgrabber), pero no tengo ni
idea de java

Si alguien puede echarme una mano o indicarme otro sitio donde puedo
encontrar ayuda, le estaría muy agradecido.

Pablo García Sánchez

unread,
Mar 23, 2009, 10:48:08 AM3/23/09
to sl-...@googlegroups.com
Consejo, si vas a trabajar con imágenes de una manera potente usa Matlab (u Octave, en su defecto ;)
--
Pablo García Sánchez
Departamento de Arquitectura y Tecnología de Computadores
Universidad de Granada
http://geneura.ugr.es/~pgarcia

Vicente Ruiz

unread,
Mar 23, 2009, 11:14:48 AM3/23/09
to sl-...@googlegroups.com
Con esto supongo que debería bastarte:

from PIL import Image
im = Image.open("nombre_de_la_imagen")
im.getpixel( (1,5) )

eso si quieres acceder a un pixel concreto, pero comentan que puede ser un poco ineficiente para recorrer pixel por pixel. Puedes cagar una matriz de la siguiente forma (una vez abierta la imagen):

pix = im.load()
print pix[x, y]

o también tienes otro método que es getdata()

Si quieres más info puedes consultar aquí:

http://www.pythonware.com/library/pil/handbook/image.htm

¡Suerte!

Un saludo,
Vicente Ruiz.

Rubén Dugo Martín

unread,
Mar 23, 2009, 11:34:42 AM3/23/09
to sl-...@googlegroups.com
Vicente, quien si no... xD

Un saludo figura!

Paquillo Dubois

unread,
Mar 23, 2009, 4:40:42 PM3/23/09
to Software libre - Universidad de Granada
Gracias Vicente.

Pero hay una cosa que se me pasó decir: solo voy a utilizar el canal
verde. Con una imagen que solo muestra el canal verde, me aparece el
mismo valor de los tres, por ejemplo, (180, 180, 180); y yo solo
quiero que me aparezca el del canal verde ¿alguna idea?
De todos modos he aprendido a obtener la matriz de píxeles con ImageJ
(simplemente exportando como texto) y esto primero no sería un
problema (aunque si se puede hacer con Python, automatizo más el
trabajo).

El último gran escollo al que me enfrento es realizar una operación al
valor de cada pixel individualmente para obtener, finalmente, la
sumatoria.
Tanto si abro el txt que genera ImageJ como si uso la matriz que
genero con PIL, me dan errores parecidos.

Usando PIL:

from PIL import Image
im = Image.open("green.jpg")
a = list(im.getdata())

for b in a:
z = b/3
print z

Me da este error:

Traceback (most recent call last):
File "/home/b/Escritorio/python/carpeta sin título/feulgen.py", line
16, in <module>
z = b/3
TypeError: unsupported operand type(s) for /: 'tuple' and 'int'

------------------
Usando el txt:

fichero = open('green.txt', 'r')

for linea in fichero:
suma = linea/3
print suma

Me da este otro error:

Traceback (most recent call last):
File "/home/b/Escritorio/python/archivo nuevo.py", line 5, in
<module>
suma = linea/3
TypeError: unsupported operand type(s) for /: 'str' and 'int'

-------------------

¿Alguna solución? Gracias por ayudarme. Un saludo.

Manuel (DraXus)

unread,
Mar 23, 2009, 6:06:10 PM3/23/09
to sl-...@googlegroups.com
Hola Paquillo,

Te respondo más abajo.

2009/3/23 Paquillo Dubois <fjrui...@gmail.com>

El error que te da es que no puedes dividir una tupla entre un entero. Prueba a imprimir b a ver lo que tiene. Imagino que será una tripleta con el valor RGB de un píxel. Si quieres coger el verde, simplemente trabaja con b[1] (segundo elemento de la tupla). OJO: Cuidado al dividir enteros, ya que te devolverá otro entero y no valores con decimales (si quieres decimales, prueba a dividir entre 3.0 por ejemplo).

------------------
Usando el txt:

fichero = open('green.txt', 'r')

for linea in fichero:
   suma = linea/3
   print suma

Me da este otro error:

Traceback (most recent call last):
 File "/home/b/Escritorio/python/archivo nuevo.py", line 5, in
<module>
   suma = linea/3
TypeError: unsupported operand type(s) for /: 'str' and 'int'

-------------------
En este caso ocurre algo similar, estas intentado divir una línea de texto del fichero entre un entero. No sé que contiene realmente el fichero, pero imagino que tendrás que hacer algún tipo de conversión de tipos.

¿Alguna solución? Gracias por ayudarme. Un saludo.
Espero haberte ayudado.

Un saludo!
  Manuel





--
WebSite: http://draxus.org

Por favor, si desea mandarme cualquier documento, utilice formatos estándar (ODF, PDF, HTML...). Gracias.

Please, if you wish to send me some documents, use standard formats (ODF, PDF, HTML...). Thanks.

Vicente Ruiz

unread,
Mar 23, 2009, 6:17:27 PM3/23/09
to sl-...@googlegroups.com
¡Hola buenas! Parece que tienes problemillas con los tipos, jeje. Como bien dice Draxus getdata() devuelve un listado de tuplas, y no un listado de valores. Para Python, las tuplas son del estilo (valor1, valor2, valor3, ...). En este caso te devuelve el valor para R, G, B y para la capa (en caso de que el formato de imagen tenga soporte para capas). Entonces tendras que ver el atributo que a ti te interesa:


from PIL import Image
im = Image.open("green.jpg")
a = list(im.getdata())

for pixel in a:
     z = pixel[1] / 3.0
     print z


Este código lo acabo de probar y funciona :)


¡Suerte!

Un saludo,
Vicente Ruiz.

PD: ¡¡Ruben!! Estos son temas de los que te molan, ¿dónde estás? :P

Paquillo Dubois

unread,
Mar 23, 2009, 7:29:16 PM3/23/09
to Software libre - Universidad de Granada
Gracias! Al final, simplemente con b[1] me generaba una lista con la
que sí podía operar.
Esto me ha servido para terminar mi programa (al menos, de momento).
Hace los cálculos mucho más rápido de lo que esperaba y sin tener que
pasar la imagen con ningún programa para tener el canal verde.
Ha superado todas las espectativas. Espero que no me falle cuando
tenga que trabajar con él. Aquí dejo, el código, gracias a todos.

Un saludo.

import math

from PIL import Image

fondo = float(raw_input('\nIndique media fondo: '))

sumatoria = 0

foto = Image.open("salamandera.jpg")

pixmap = list(foto.getdata())

for pixels in pixmap:

logaritmo = -math.log10(pixels[1]/fondo)

if logaritmo > 0.16:

sumatoria += logaritmo

print '\nLa suma total es %f' % (sumatoria)

Rubén Dugo Martín

unread,
Mar 23, 2009, 8:36:29 PM3/23/09
to sl-...@googlegroups.com
Vicente te cedo cortesmente el problema que tu te explicas mejor ;)

Paquillo Dubois

unread,
Mar 24, 2009, 10:27:59 AM3/24/09
to Software libre - Universidad de Granada
Forzando el programa he encontrado que cuando uso imágenes de más de
500x500 pixeles

Indique media fondo: 180

Traceback (most recent call last):
File "/media/disk/feulgen image analysis/feulgen imagen.py", line
23, in <module>
logaritmo = -math.log10(pixels[1]/fondo)
OverflowError: math range error

¿Alguna solución?

Gracias por todo.

Mario

unread,
Mar 24, 2009, 10:52:25 AM3/24/09
to sl-...@googlegroups.com
Eso es que está haciendole el logaritmo a cero (que no está definido). En ese caso deberas poner algo como:

 if pixels[1] != 0
  ... lo que tenias
 else
   logaritmo = el valor que creas que deba ser (mínimo/máximo/0...).

Paquillo Dubois

unread,
Mar 24, 2009, 12:52:18 PM3/24/09
to Software libre - Universidad de Granada
Gracias a todos, de nuevo, ahor va perfecto.

On 24 mar, 15:52, Mario <mari...@gmail.com> wrote:
> Eso es que está haciendole el logaritmo a cero (que no está definido). En
> ese caso deberas poner algo como:
>
> if pixels[1] != 0
> ... lo que tenias
> else
> logaritmo = el valor que creas que deba ser (mínimo/máximo/0...).
>
Reply all
Reply to author
Forward
0 new messages