from matplotlib import pyplot as plt # Biblioteca para crear graficas y mostrar las imágenes en pantalla from skimage import data # Paquete con imágenes de prueba from skimage import io # Paquete para lectura/escritura de imágenes from skimage import color # Paquete con las operaciones de transformaciones entre espacios de color from skimage import exposure # Paquete con las funciones para calcular y alterar el histograma #################### import skdemo # Paquete ESPECIAL ADJUNTO con algunas funciones extra de visualización # Cargamos la imagen img = data.camera() # Calcula y muestra el histograma de la imagen skdemo.imshow_with_histogram(img) # Expansión del Histograma # Como vimos en clase, mejorar el contraste de una imagen nos permite identificar más fácilmente los objetos de interés en la imagen, además que facilita el proceso de su segmentación y la extracción de sus características, esto bien sea a ojo o utilizando diferentes tipos de algoritmos. # Eche un vistazo a la imagen del fotógrafo y a su histograma: # Observe detenidamente el histograma: dado que la imagen es de tipo uint8, los valores de niveles de intensidad van de 0 a 255. # Advierta que hay algunos pocos píxeles hacia el valor 255 y otros pocos por debajo del 10. Esto nos indica que la imagen no # tiene una distribución adecuada de los píxeles cercanos al blanco. # En este caso, podemos aplicar una Expansión del Histograma: # Los puntos que se están moviendo son m=10 y M=180, de acuerdo a la ecuación presentada en las diapositivas img_contraste = exposure.rescale_intensity(img, in_range=(10, 180))
from skimage import color lab_image = color.rgb2lab(color_image) # In[13]: luminance, a, b = np.rollaxis(lab_image, axis=-1) titles = ['luminance', 'a-component', 'b-component'] skdemo.imshow_all(luminance, a, b, titles=titles) # Notice the eyes are really dark in the middle image, i.e. the "A"-component of the LAB color space. We should use that for thresholding. We don't want to just guess values for thresholding; instead, let's look at a histogram: # In[14]: skdemo.imshow_with_histogram(lab_image) # I've cheated here and reused our RGB histogram for LAB space. The image is wrong because the image isn't RGB, but the histograms are still valid. Note that we're plotting in RGB order, so the "A" commponent here is green. Since the eyes are very dark in the "A" image above, we'd like to select the left tail of the green histogram---roughly at 0: # In[15]: plt.imshow(a < 0) # To get the nose, notice that it's quite bright in the "A" component, so lets grab the right tail of the green histogram (> 30). # In[16]: plt.imshow(a > 30) # Combining those two, plus an extra bit of thresholding to blacken the pupil, gives:
# <codecell> # Uncomment to see help on `imshow_with_histogram` #skdemo.imshow_with_histogram? # <markdowncell> # <notes> # Using this function, let's look at the histogram of a grayscale image: # <codecell> image = data.camera() skdemo.imshow_with_histogram(image); # <markdowncell> # <notes> # An image histogram shows the number of pixels at each intensity value (or # range of intensity values, if values are binned). Low-intensity values are # closer to black, and high-intensity values are closer to white. # # Notice that there's a large peak at an intensity of about 10: This peak # corresponds with the man's nearly black coat. The peak around the middle of # the histogram is due to the predominantly gray tone of the image. # <markdowncell> # <notes>
# For this section, we're going to use a custom plotting function that adds a few tweaks to pretty-it-up: # * Plot the image next to the histogram # * Plot each RGB channel separately # * Automatically flatten channels # * Select reasonable bins based on the image's `dtype` # In[21]: get_ipython().magic(u'pinfo skdemo.imshow_with_histogram') # Using this function, let's look at the histogram of a grayscale image: # In[22]: image = data.camera() skdemo.imshow_with_histogram(image) # An image histogram shows the number of pixels at each intensity value (or range of intensity values, if values are binned). Low-intensity values are closer to black, and high-intensity values are closer to white. # # Notice that there's a large peak at an intensity of about 10: This peak corresponds with the man's nearly black coat. The peak around the middle of the histogram is due to the predominantly gray tone of the image. # Now let's look at our color image: # In[23]: cat = data.chelsea() skdemo.imshow_with_histogram(cat) # As you can see, the intensity for each RGB channel is plotted separately. Unlike the previous histogram, these histograms almost look like Gaussian distributions that are shifted. This reflects the fact that intensity changes are relatively gradual in this picture: There aren't very many uniform instensity regions in this image. # # An image with well-defined color regions gives a very different histogram:
# <codecell> import numpy as np from matplotlib import cm, pyplot as plt import skdemo plt.rcParams['image.cmap'] = 'cubehelix' plt.rcParams['image.interpolation'] = 'none' # <codecell> from skimage import io image = io.imread('../images/chromosomes.tif') skdemo.imshow_with_histogram(image); # <markdowncell> # Let's separate the channels so we can work on each individually. # <codecell> protein, centromeres, chromosomes = image.transpose((2, 0, 1)) # <markdowncell> # Getting the centromeres is easy because the signal is so clean:
# 8. Lea la imagen de prueba (in001637.jpg) en la variable test test = io.imread("highway/in001637.jpg") # 9. Restar las imagenes de test y background, haciendoq ue la suma sea entera out = (test.astype(int) - background.astype(int)) # 10. Sature los píxeles con valores <0 y >255 out[out < 0] = 0 out[out > 255] = 255 # 11. Cambie el tipo de la imagen a uint8 out = out.astype(np.uint8) # 12. Muestre la imagen resultante y su histograma skdemo.imshow_with_histogram(out) # 13. Haga una expansión de la imagen en el rango 0, 180 out2 = exposure.rescale_intensity(out, in_range=(0, 180)) # 14. Umbralice cada canal por separado mantenga los píxeles >= 128 Ro = out2[:,:,0] >= 128; Go = out2[:,:,1] >= 128; Bo = out2[:,:,2] >= 128; # 15. Genere una imagen de salida que corresponda al OR entre los canales out3 = np.logical_or(Ro, Go) out3 = np.logical_or(out3, Bo) # 16. Muestre los objetos de interés en la imagen (out3) plt.imshow(Bo, cmap="gray")
# Con este nos aseguramos que las imagenes en niveles de gris, se vean como tal siempre. plt.rcParams['image.cmap'] = 'gray' plt.rcParams['image.interpolation'] = 'none' #Segmentación por Umbral Simple¶ #Este es el tipo de segmentación más simple y consiste en utilizar el histograma para determinar #el nivel de intensidad que permite separar a los objetos del fondo de la imagen. # Cargamos la imagen de prueba img_1 = io.imread('imagenes/rice.png') img_1 = color.rgb2gray(img_1) # Visualizamos la imagen de prueba y su histograma skdemo.imshow_with_histogram(img_1) img_1.shape # Al analizar el histograma se puede observar que los objetos de interés, cuyo color predominante es muy claro, # tienen valores por encima del valor 125. Ese valor es el que se utilza como umbral. # En Python, cuando se usa NumPy, el proceso de umbralización es muy simple: # La umbralización consiste en simplmente comparar los píxeles de la imagen con el valor definido img_BW = img_1 >= 125 plt.imshow(img_BW) # Note que a pesar de que los objetos son más claros que el fondo de la imagen, este método no funciona muy bien con la imagen # de los arroces. Esto sucede porque la iluminación en la imagen es no homogenea. Cuando esto sucede al aumentar el valor del