Corregir una iluminación no uniforme y analizar objetos del primer plano
Este ejemplo muestra cómo mejorar una imagen como paso de preprocesamiento antes del análisis. En este ejemplo, se corrige la iluminación de fondo no uniforme y se convierte la imagen a una imagen binaria para que sea más fácil identificar objetos en el primer plano (granos individuales de arroz). Después, puede analizar los objetos, como encontrar el área de cada grano de arroz, y calcular estadísticas para todos los objetos de la imagen.
Preprocesar la imagen
Lea una imagen en el espacio de trabajo.
I = imread('rice.png');
imshow(I)
La iluminación de fondo es más brillante en el centro de la imagen que en la parte inferior. Preprocese la imagen para hacer que la iluminación de fondo sea más uniforme.
Como primer paso, elimine todo el primer plano (granos de arroz) utilizando la apertura morfológica. La operación de apertura elimina objetos pequeños que no pueden contener por completo el elemento estructurante. Defina un elemento estructurante con forma de disco y con un radio de 15 que quepa por completo dentro de un único grano de arroz.
se = strel('disk',15)
se = strel is a disk shaped structuring element with properties: Neighborhood: [29x29 logical] Dimensionality: 2
Para realizar la apertura morfológica, utilice imopen
con el elemento estructurante.
background = imopen(I,se); imshow(background)
Reste la imagen de aproximación de fondo, background
, de la imagen original, I
, y visualice la imagen resultante. Después de restar la imagen con el fondo ajustado de la imagen original, la imagen resultante tiene un fondo uniforme, pero es un poco oscura para el análisis.
I2 = I - background; imshow(I2)
Utilice imadjust
para aumentar el contraste de la imagen procesada I2
saturando el 1% de los datos en las intensidades tanto bajas como elevadas y estirando los valores de intensidad para que abarquen el intervalo dinámico uint8
.
I3 = imadjust(I2); imshow(I3)
Observe que los dos pasos anteriores se pueden sustituir por un paso único utilizando imtophat
, que calcula primero la apertura morfológica y, después, la resta de la imagen original.
I2 = imtophat(I,strel('disk',15));
Cree una versión binaria de la imagen procesada para poder usar funciones de la toolbox para el análisis. Utilice la función imbinarize
para convertir la imagen en escala de grises en una imagen binaria. Elimine el ruido de fondo de la imagen con la función bwareaopen
.
bw = imbinarize(I3); bw = bwareaopen(bw,50); imshow(bw)
Identificar objetos en la imagen
Ahora que ha creado una versión binaria de la imagen original, puede realizar análisis de objetos de la imagen.
Encuentre todos los componentes conectados (objetos) en la imagen binaria. La precisión de los resultados depende del tamaño de los objetos, del parámetro de conectividad (4, 8 o arbitrario) y de si hay objetos que se tocan (en cuyo caso se pueden etiquetar como un único objeto). Algunos de los granos de arroz de la imagen binaria bw
se tocan.
cc = bwconncomp(bw,4)
cc = struct with fields:
Connectivity: 4
ImageSize: [256 256]
NumObjects: 95
PixelIdxList: {1x95 cell}
cc.NumObjects
ans = 95
Visualice el grano de arroz con la etiqueta 50 en la imagen.
grain = false(size(bw)); grain(cc.PixelIdxList{50}) = true; imshow(grain)
Visualice todos los componentes conectados en la imagen creando una matriz de etiquetas y, después, visualizándola como una imagen indexada de pseudocolor.
Utilice labelmatrix
para crear una matriz de etiquetas a partir de la salida de bwconncomp
. Observe que labelmatrix
almacena la matriz de etiquetas en la clase numérica más pequeña necesaria para el número de objetos.
labeled = labelmatrix(cc);
whos labeled
Name Size Bytes Class Attributes labeled 256x256 65536 uint8
Utilice label2rgb
para elegir el mapa de colores, el color de fondo y cómo los objetos de la matriz de etiquetas se asignan a los colores del mapa de colores. En la imagen de pseudocolor, la etiqueta que identifica cada objeto en la matriz de etiquetas se asigna a un color diferente en una matriz de mapa de colores asociada.
RGB_label = label2rgb(labeled,'spring','c','shuffle'); imshow(RGB_label)
Calcular estadísticas basadas en áreas
Calcule el área de cada objeto de la imagen utilizando regionprops
. Cada grano de arroz es un componente conectado en la estructura cc
.
graindata = regionprops(cc,'basic')
graindata=95×1 struct array with fields:
Area
Centroid
BoundingBox
Cree un vector grain_areas
nuevo que contenga la medida de área de cada grano.
grain_areas = [graindata.Area];
Encuentre el área del componente n.º 50.
grain_areas(50)
ans = 194
Encuentre y muestre el grano con el área más pequeña.
[min_area, idx] = min(grain_areas)
min_area = 61
idx = 16
grain = false(size(bw)); grain(cc.PixelIdxList{idx}) = true; imshow(grain)
Utilice el comando histogram
para crear un histograma de áreas de granos de arroz.
histogram(grain_areas)
title('Histogram of Rice Grain Area')
Consulte también
imopen
| bwareaopen
| bwconncomp
| regionprops
| imadjust
| imbinarize
| label2rgb
| labelmatrix
| imread
| imshow