Saltar al contenido

¿Cómo agrupar y resaltar un grupo de píxeles en una imagen usando OpenCV?

Te damos la bienvenida a nuestra web, en este sitio encontrarás la respuesta que buscabas.

Solución:

Si lo entiendo correctamente, desea resaltar las diferencias entre las imágenes de entrada y salida en una nueva imagen. Para hacer esto, puede adoptar un enfoque cuantitativo para determinar las discrepancias exactas entre las imágenes utilizando el Índice de similitud estructural (SSIM) que se introdujo en Evaluación de la calidad de la imagen: de la visibilidad de errores a la similitud estructural. Este método ya está implementado en la biblioteca scikit-image para el procesamiento de imágenes. Puedes instalar scikit-image con pip install scikit-image.

los skimage.measure.compare_ssim() la función devuelve un score y un diff imagen. los score representa el índice de similitud estructural entre las dos imágenes de entrada y puede caer entre el rango [-1,1] con valores más cercanos a uno que representa una mayor similitud. Pero como solo le interesa saber dónde difieren las dos imágenes, la diff la imagen es en lo que nos centraremos. Específicamente, el diff La imagen contiene las diferencias de imagen reales con las regiones más oscuras que tienen más disparidad. Las áreas más grandes de disparidad se resaltan en negro, mientras que las diferencias más pequeñas están en gris. Aquí esta la diff imagen

ingrese la descripción de la imagen aquí

Si observa de cerca, hay áreas grises ruidosas probablemente debido a .jpg Compresión con pérdida. Entonces, para obtener un resultado más limpio, realizamos operaciones morfológicas para suavizar la imagen. Obtendríamos un resultado más limpio si las imágenes utilizaran un formato de compresión de imágenes sin pérdidas como .png. Después de limpiar la imagen, destacamos las diferencias en verde.

ingrese la descripción de la imagen aquí

from skimage.measure import compare_ssim
import numpy as np
import cv2

# Load images and convert to grayscale
image1 = cv2.imread('1.jpg')
image2 = cv2.imread('2.jpg')
image1_gray = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
image2_gray = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)

# Compute SSIM between two images
(score, diff) = compare_ssim(image1_gray, image2_gray, full=True)

# The diff image contains the actual image differences between the two images
# and is represented as a floating point data type in the range [0,1] 
# so we must convert the array to 8-bit unsigned integers in the range
# [0,255] before we can use it with OpenCV
diff = 255 - (diff * 255).astype("uint8")

cv2.imwrite('original_diff.png',diff)

# Perform morphological operations
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
opening = cv2.morphologyEx(diff, cv2.MORPH_OPEN, kernel, iterations=1)
close = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel, iterations=1)
diff = cv2.merge([close,close,close])

# Color difference pixels
diff[np.where((diff > [10,10,50]).all(axis=2))] = [36,255,12]

cv2.imwrite('diff.png',diff)

Creo que la mejor manera es simplemente limitar su imagen y aplicar Transformaciones Morfológicas.

Tengo los siguientes resultados.

Umbral + Morfológico:

Threashold + Morfológico

Seleccione el componente más grande:

resultado

usando este código:

cv::Mat result;
cv::Mat img = cv::imread("fOTmh.jpg");

//-- gray & smooth image
cv::cvtColor(img, result, cv::COLOR_BGR2GRAY);
cv::blur(result, result, cv::Size(5,5));

//-- threashold with max value of the image and smooth again!
double min, max;
cv::minMaxLoc(result, &min, &max);
cv::threshold(result, result, 0.3*max, 255, cv::THRESH_BINARY);
cv::medianBlur(result, result, 7);

//-- apply Morphological Transformations
cv::Mat se = getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(11, 11));
cv::morphologyEx(result, result, cv::MORPH_DILATE, se);
cv::morphologyEx(result, result, cv::MORPH_CLOSE, se);

//-- find the largest component
vector > contours;
vector hierarchy;
cv::findContours(result, contours, hierarchy, cv::RETR_LIST, cv::CHAIN_APPROX_NONE);
vector *l = nullptr;
for(auto &&c: contours)

//-- expand and plot Rect around the largest component
cv::Rect r = boundingRect(*l);
r.x -=10;
r.y -=10;
r.width +=20;
r.height +=20;
cv::rectangle(img, r, cv::Scalar::all(255), 3);


//-- result
cv::resize(img, img, cv::Size(), 0.25, 0.25);
cv::imshow("result", img);

Código Python:

import cv2 as cv

img = cv.imread("ELA_Final.jpg")

result = cv.cvtColor(img, cv.COLOR_BGR2GRAY);
result = cv.blur(result, (5,5));

minVal, maxVal, minLoc, maxLoc = cv.minMaxLoc(result)
ret,result = cv.threshold(result, 0.3*maxVal, 255, cv.THRESH_BINARY)
median = cv.medianBlur(result, 7)

se = cv.getStructuringElement(cv.MORPH_ELLIPSE,(11, 11));
result = cv.morphologyEx(result, cv.MORPH_DILATE, se);
result = cv.morphologyEx(result, cv.MORPH_CLOSE, se);

_,contours, hierarchy = cv.findContours(result,cv.RETR_LIST, cv.CHAIN_APPROX_NONE)

x = []

for eachCOntor in contours:
    x.append(len(eachCOntor))
m = max(x)
p = [i for i, j in enumerate(x) if j == m]

color = (255, 0, 0) 
x, y, w, h = cv.boundingRect(contours[p[0]])
x -=10
y -=10
w +=20
h +=20
cv.rectangle(img, (x,y),(x+w,y+h),color, 3)

img =  cv.resize( img,( 1500, 700), interpolation = cv.INTER_AREA)
cv.imshow("result", img)
cv.waitKey(0)

Eres capaz de añadir valor a nuestra información participando con tu experiencia en las críticas.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *