versiones guia espaƱol descargar actualizar algorithm matlab opencv image-processing computer-vision

algorithm - guia - Detecta puntos negros del fondo del color



qgis manual (3)

Mi breve pregunta

¿Cómo detectar los puntos negros en las siguientes imágenes? (Pego solo una imagen de prueba para que la pregunta parezca compacta. Se pueden encontrar más imágenes → aquí ← ).

Mi larga pregunta

Como se muestra arriba, el color de fondo es aproximadamente azul, y el color de los puntos es "negro". Si elige un píxel negro y mide su color en RGB, el valor puede ser (0, 44, 65) o (14, 69, 89) ... Por lo tanto, no podemos establecer un rango para decir que el píxel es parte del punto negro o del fondo.

Probé 10 imágenes de diferentes colores, pero espero poder encontrar un método para detectar los puntos negros de un fondo más complicado que puede estar formado por tres o más colores, siempre que los ojos humanos puedan identificar fácilmente los puntos negros. Se pueden omitir algunos puntos extremadamente pequeños o borrosos.

Trabajo previo

El mes pasado, hice una pregunta similar en stackoverflow, pero no obtuve una solución perfecta, aunque sí algunas respuestas excelentes. Encuentre más detalles sobre mi trabajo si está interesado.

Aquí están los métodos que he probado:

  1. Convertir a escala de grises o el brillo de la imagen. La dificultad es que no puedo encontrar un umbral adaptativo para hacer binarización. Obviamente, convertir una imagen en color a escala de grises o usar el brillo (HSV) perderá mucha información útil. El algoritmo de Otsu que calcula el umbral adaptativo tampoco puede funcionar.

  2. Cálculo del histograma RGB . En mi última pregunta, el método de Natan es estimar el color negro por histograma. Es un ahorro de tiempo, pero el umbral de adaptación también es un problema.

  3. Agrupación . Intenté clustering k-means y encontré que es bastante efectivo para el fondo que solo tiene un color. La escasez (ver mi propia respuesta) es que necesito establecer el número de centros de clustering por adelantado, pero no sé cómo será el fondo. ¡Además, es demasiado lento ! Mi aplicación es para capturar en tiempo real en iPhone y ahora puede procesar 7 ~ 8 fotogramas por segundo usando k-means (20 FPS es bueno, creo).

Resumen

Creo que no solo los colores similares, sino también los píxeles adyacentes deberían estar "agrupados" o "combinados" para extraer los puntos negros. Por favor, guíame una forma correcta de resolver mi problema. Cualquier consejo o algoritmo será apreciado. No hay almuerzo gratis, pero espero una mejor compensación entre costo y precisión.


Pude obtener algunos primeros pasos bastante bonitos al convertir al espacio de color HSV con rgb2hsv , y luego usar las funciones de procesamiento de imágenes de la caja de herramientas imopen e imregionalmin en el canal de valores:

rgb = imread(''6abIc.jpg''); hsv = rgb2hsv(rgb); openimg = imopen(hsv(:, :, 3), strel(''disk'', 11)); mask = imregionalmin(openimg); imshow(rgb); hold on; [r, c] = find(mask); plot(c, r, ''r.'');

Y las imágenes resultantes (para la imagen en la pregunta y una elegida de su enlace):

Puede ver algunos falsos positivos y puntos perdidos, así como algunos puntos que están etiquetados con puntos múltiples, pero algunos refinamientos (como la modificación del elemento de estructura utilizado en el paso de apertura) podrían limpiarlos.


Era curioso probar con mi antiguo código de buscador de 2d en las imágenes sin ningún umbral ni consideraciones de color, realmente crudo, ¿no crees?

im0=imread(''Snap10.jpg''); im=(abs(255-im0)); d=rgb2gray(im); filter=fspecial(''gaussian'',16,3.5); p=FastPeakFind(d,0,filter); imagesc(im0); hold on plot(p(1:2:end),p(2:2:end),''r.'')

El código que estoy usando es un simple buscador local de máximos 2D, hay algunos falsos positivos, pero en general esto captura la mayoría de los puntos sin duplicación. El filtro que estaba usando era 2d gaussiano de ancho y estándar similar a un blob típico (lo mejor habría sido obtener un filtro coincidente para su problema). Una versión más sofisticada que trata los colores (rgb2hsv?) Podría mejorar aún más ...


Aquí hay una versión simplificada extraodinariamente, que se puede ampliar para que sea RGB completa, y tampoco usa la biblioteca de procesamiento de imágenes. Básicamente puede hacer una convolución en 2-D con una imagen de filtro (que es un ejemplo del punto que está buscando), y desde los puntos donde la convolución devuelve los valores más altos, son las mejores coincidencias para los puntos. Entonces puedes, por supuesto, llegar a ese límite. Aquí hay un ejemplo simple de imagen binaria de eso.

%creating a dummy image with a bunch of small white crosses im = zeros(100,100); numPoints = 10; % randomly chose the location to put those crosses points = randperm(numel(im)); % keep only certain number of points points = points(1:numPoints); % get the row and columns (x,y) [xVals,yVals] = ind2sub(size(im),points); for ii = 1:numel(points) x = xVals(ii); y = yVals(ii); try % create the crosses, try statement is here to prevent index out of bounds % not necessarily the best practice but whatever, it is only for demonstration im(x,y) = 1; im(x+1,y) = 1; im(x-1,y) = 1; im(x,y+1) = 1; im(x,y-1) = 1; catch err end end % display the randomly generated image imshow(im) % create a simple cross filter filter = [0,1,0;1,1,1;0,1,0]; figure; imshow(filter) % perform convolution of the random image with the cross template result = conv2(im,filter,''same''); % get the number of white pixels in filter filSum = sum(filter(:)); % look for all points in the convolution results that matched identically to the filter matches = find(result == filSum); %validate all points found sort(matches(:)) == sort(points(:)) % get x and y coordinate matches [xMatch,yMatch] = ind2sub(size(im),matches);

Sugeriría mucho consultar la documentación de conv2 en el sitio web de MATLAB.