Mostrando entradas con la etiqueta procesado. Mostrar todas las entradas
Mostrando entradas con la etiqueta procesado. Mostrar todas las entradas
jueves, 11 de abril de 2013
Máscara de enfoque con Python
Código que implementa una máscara de enfoque para una imagen. Está escrito en Python con el apoyo de las librerías OpenCV, numpy y scipy. Para ejecutarlo es necesario emplear Python 2.7.4
En la próxima entrada comentaré el código en profundidad, explicando como se realiza la convolución bidimensional y el efecto de la máscara de enfoque sobre la imagen.
import numpy as np
import cv2
from scipy import ndimage, signal
#filtro de enfoque
# -*- coding: utf-8 -*-
def gauss2d(k, std): #gaussiana bidimensional
rows=2*k+1
cols=2*k+1
gaussian1d=signal.gaussian(cols,std) #gaussiana unidimensional
kernel_gauss=np.ndarray((rows,cols),"float") #mascara/kernel
for i in range(0,rows):
for j in range(0,cols):
kernel_gauss[i,j]=gaussian1d[i]*gaussian1d[j]
kernel_gauss=kernel_gauss/kernel_gauss.sum() #norm. de la gaussiana
return kernel_gauss
def conv2d(img, krnl): #convolucion bidimensional
rows=img.shape[0]-krnl.shape[0]+1
cols=img.shape[1]-krnl.shape[1]+1
output=np.ndarray((rows,cols), "float")
kernel_reversed=np.rot90(np.rot90(kernel))
for i in range(0, output.shape[0]):
for j in range(0, output.shape[1]):
img_patch=img[i:i+len(krnl),j:j+len(krnl)]
y=max((kernel_reversed*img_patch).sum(),0)
z=min(y,255)
output[i,j]=z
return output
def sharp(k,std): #creación de la mascara de enfoque
rows=2*k+1
cols=2*k+1
kernel_g=gauss2d(k,std)
kernel=np.zeros((rows,cols),"float")
kernel[k,k]=2
kernel=kernel-kernel_g
return kernel
def apply_filter(image, kernel): #rutina para aplicarle el filtro a la imagen
if len(img.shape) == 2: #blanco y negro (1 canal y transparencia)
img_filt = conv2d(img, kernel)
else: #color (3 canales y transparencia)
img_filt = []
for channel in range(img.shape[2]):
img_filt.append(conv2d(img[:,:,channel], kernel))
img_filt = cv2.merge(img_filt)
return img_filt
k=5 #radio de la gaussiana
std=3.0 #desviacion estandar de la gaussiana
#k y std son los parámetros que controlan la cantidad de enfoque que
#se quieres aplicar a la imagen
img=cv2.imread('ruta de la imagen a leer') #leer imagen
img=img.astype("float")
kernel=sharp(k,std)
img_filt=apply_filter(img, kernel)
cv2.imwrite('ruta de la imagen a escribir',img_filt) #escribir imagen
lunes, 13 de agosto de 2012
Umbralización local o adaptativa.
En muchas aplicaciones, no se puede obtener un umbral global para un histograma, es decir, no se puede obtener una buena segmentación con un único umbral para toda la imagen. Esto ocurre cuando el fondo no es constante y el contraste de los objetos varía en la imagen, por lo que la umbralización daría buenos resultados en una parte de la imagen, pero para el resto de la imagen, la segmentación no sería la adecuada.
Si las variaciones del fondo de la imagen pueden ser descritas a través de funciones conocidas, dependientes de la posición en la imagen, se podría intentar corregir la segmentación utilizando la corrección de niveles de gris; para que, posteriormente, la aplicación de un único umbral a toda la imagen, diera buenos resultados en la segmentación.Otra solución sería el uso de la umbralización local o adaptativa.
Los umbrales locales pueden ser determinados dividiendo una imagen en subimágenes y calculando los umbrales de dichas subimágenes, o examinando las intensidades de la imagen en los alrededores de cada píxel. En el primer método, primero, se divide una imagen en subimágenes rectangulares solapadas, y se obtienen los histogramas de cada subimagen. Estas subimágenes deben ser los suficientemente grandes como para abarcar el fondo, y el objeto en cuestión. Si una subimagen tiene un histograma bimodal, el mínimo entre los dos picos determinará el umbral local. En caso que el histrograma sea unimodal, el umbral se obtendrá por interpolación de los umbrales locales de las subimágenes adyacentes. Por último, es necesario realizar una segunda interpolación para encontrar los umbrales adecuados a cada píxel.
En el último método, se puede seleccionar un umbral mediante el valor medio de la distribución local de intensidad. Para esto, se pueden usar otro tipo de medidas estadísticas, tales como la media de las desviaciones estándar, la media de los valores máximos y mínimos, o medidas basadas en los valores de los gradientes de intensidad.
La umbralización local es computacionalmente más costosa que la global. Es muy útil a la hora de segmentar objetos en fondos no homogéneos, y para extraer regiones muy pequeñas y dispersas.
miércoles, 8 de agosto de 2012
Pure Data-PD
Pure Data (PD) es un lenguaje de programación gráfico, en tiempo real, para audio, vídeo y procesado de gráficos. Es la tercera rama más importante de la familia de lenguajes de programación patcher conocida como Max (Max / FTS, ISPW Max, Max / MSP,jMax, etc), y fue originalmente desarrollado por Miller Puckette en el IRCAM. Aunque el núcleo de PD sigue siendo desarrollado y mantenido por Miller Puckette, se incluye el trabajo de muchos desarrolladores, por lo que todo el paquete supone un gran esfuerzo comunitario.
PD es un ejemplo de lenguaje de programación de "flujo de datos". Es decir, las funciones u "objetos" son conectados, o "parcheados", unos con otros en un ambiente gráfico que modela el flujo de control y de los datos (audio, vídeo y/o gráficos). Por lo que PD es un lenguaje de programación especialmente orientado al procesado de señales.
El entorno de programación posee una base modular de código, en el que los objetos son utilizados como elementos de construcción en el desarrollo de programas en Pure Data. Además, el programa se hace arbitrariamente extensible a través de una API pública, por lo que alienta a otros desarrolladores a añadir sus propias rutinas, ya sea en el lenguaje de programación C o, con la ayuda de otros lenguajes externos. Estas unidades de código modulares y reusables, que resultan de la programación de algoritmos en PD, se suelen denominar "patches", y son usadas como programas independientes y compartidas libremente entre la comunidad de usuarios de PD.
Para el desarrollo de los ejemplos gráficos que se presentarán en posteriores posts en este apartado se emplea la líbreria GEM (Graphics Environment for Multimedia),que está indicada para la generación de gráficos OpenGL en tiempo real.
lunes, 6 de agosto de 2012
Segmentación de imágenes médicas
El principal objetivo durante el proceso de segmentación es realizar la partición de una imagen en regiones (denominadas como clases), las cuáles son homogéneas respecto a una o más características. La segmentación representa una importante herramienta para el procesado de imágenes médicas, y ha sido útil en aplicaciones como la cuantificación de lesiones en esclerosis múltiple, simulaciones quirúrgicas, medidas de volumen en tumores, etc.
Existen una amplia variedad de técnicas de segmentación, aunque no existe ningún estándar de segmentación de imágenes que produzca resultados satisfactorios en cualquier tipo de aplicación. Los objetivos de la segmentación varían en función del estudio en cuestión y del tipo de modalidad de imagen médica empleada. Por lo que, las diferentes suposiciones que se hagan sobre las imágenes conducirán a una gran variedad de algoritmos de segmentación.
En imágenes médicas, la segmentación es importante en cuanto a la extracción de características, a la realización de medidas sobre la imagen y la representación de la misma. En algunas aplicaciones es útil para la clasificación de píxeles tanto en regiones anatómicas, como los huesos, músculos o vasos sanguíneos; como en regiones patológicas como cánceres, deformidades en los tejidos, etc. En algunos estudios el objetivo es dividir la imagen en materia gris, materia blanca y espacios del líquido cefalorraquídeo del cerebro; mientras que en otros, lo que se hace es extraer, de la imagen, la estructura afectada completa; como se hace con los tumores mamarios en MRI.
Las técnicas de segmentación se pueden clasificar de diferentes maneras, en este caso, en función del esquema de clasificación:
-Manual, semiautomático y automático.
-En función de los píxeles (métodos locales) y en función de regiones (métodos globales).
-Delineación manual, segmentación de bajo nivel (umbralización, crecimiento de regiones) y en función de modelos (programación dinámica, detección de contornos).
-Clásica (umbralización, técnicas basadas en los bordes, y en las regiones), estadística, borrosa y técnicas de redes neuronales.
Las técnicas de segmentación más usadas se pueden clasificar en dos amplias categorías; en técnicas de segmentación de regiones, que busca las regiones que satisfagan un determinado criterio, y en técnicas de segmentación en función de los bordes, que persigue encontrar la frontera entre tejidos con diferentes características.
La umbralización, es un método de segmentación de regiones muy común. En esta técnica se establece un umbral y entonces la imagen se divide en píxeles con valores menores que el umbral, y en los que su valor supera, o iguala, al umbral establecido. Hay diversos métodos de umbralización como los métodos globales basados en histogramas de niveles de gris, métodos globales basados en propiedades locales, selección de un umbral local y umbralización dinámica. Los algoritmos de clustering logran la segmentación en regiones mediante la partición de la imagen en grupos de píxeles parecidos. La operaciónbásica de estos algoritmos consiste en asignar cada píxel al grupo que mejor represente el valor del vector característico, en relación con la característica de interés.
El crecimiento de regiones, es otro tipo de algoritmos de segmentación de imágenes que asigna píxeles adyacentes o regiones al mismo segmento, si su valor son lo suficientemente parecidos, de acuerdo con un criterio establecido.
Las técnicas de segmentación de imágenes han estado encaminadas a un tipo concreto de imágenes (MRI, CT, PET…), aunque la mejora de los algoritmos de segmentación está enfocada a combinar imágenes de múltiples fuentes (segmentación multiespectral), o la integración de las imágenes a lo largo del tiempo (segmentación dinámica o temporal).
Suscribirse a:
Entradas (Atom)