2012-04-21 36 views
11

quiero detectar el logotipo dentro de la imagen para eliminarlo, tengo una idea que es buscar objetos que tienen la gran cantidad de píxeles y luego eliminar, otra idea es recorrer todos los píxeles blancos (he invertido mi imagen) y busque píxeles que formen una gran región y luego eliminen esta región, ¿hay algún algoritmo mejor que este, y qué métodos en opencv me ayudarán a detectar objetos de gran número de píxeles?cómo detectar la región de gran cantidad de píxeles blancos usando opencv?

Respuesta

32

Tengo un método para hacerlo. No sé si este método se aplica a todos, pero funciona bien aquí.

A continuación se muestra el código (en Python):

imagen Primera convertir a escala de grises, cambiar el tamaño de la imagen, se aplica umbral, y crea una imagen de la máscara del mismo tipo y tamaño de esa imagen en escala de grises de redimensionado. (La imagen de la máscara es solo una imagen en negro)

import cv2 
import numpy as np 

img = cv2.imread('bus.png') 
img = cv2.resize(img,(400,500)) 
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 
ret,gray = cv2.threshold(gray,127,255,0) 
gray2 = gray.copy() 
mask = np.zeros(gray.shape,np.uint8) 

Ahora encuentre los contornos en la imagen del umbral. Filtra el contorno del área entre 500 y 5000. Probablemente será una gran mancha blanca, obviamente no letras. (Recuerda, esta área es particular para esta imagen. No sé sobre tus otras imágenes. Tendrás que encontrarla tú mismo). Ahora dibuja este contorno en la imagen de la máscara llena de color blanco.

contours, hier = cv2.findContours(gray,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) 
for cnt in contours: 
    if 200<cv2.contourArea(cnt)<5000: 
     cv2.drawContours(img,[cnt],0,(0,255,0),2) 
     cv2.drawContours(mask,[cnt],0,255,-1) 

Below is the detected contour image:

detected contour drawn on the input image

Next is the mask image:

New mask image

Ahora Invertir imagen usando la función cv2.bitwise_not. Allí tiene la opción de dar máscara donde le damos nuestra imagen de máscara para que funcione solo en el área de la imagen de entrada donde hay blanco en la imagen de la máscara.

cv2.bitwise_not(gray2,gray2,mask) 

Y, finalmente, mostrar la imagen:

cv2.imshow('IMG',gray2) 
cv2.waitKey(0) 
cv2.destroyAllWindows() 

Y aquí está el resultado:

enter image description here


NOTA:

El método anterior se realiza para conservar "NARANJA" en el cuadrado blanco. Es por eso que algunos artefactos están ahí. Si no quieres ese naranja también, puede ser más preciso.

Simplemente encuentre el rectángulo delimitador para los contornos filtrados por área y dibuje el rectángulo relleno de color negro.

Código:

import cv2 
import numpy as np 

img = cv2.imread('bus.png') 
img = cv2.resize(img,(400,500)) 
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 
ret,gray = cv2.threshold(gray,127,255,0) 
gray2 = gray.copy() 

contours, hier = cv2.findContours(gray,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) 
for cnt in contours: 
    if 200<cv2.contourArea(cnt)<5000: 
     (x,y,w,h) = cv2.boundingRect(cnt) 
     cv2.rectangle(gray2,(x,y),(x+w,y+h),0,-1) 

cv2.imshow('IMG',gray2) 
cv2.waitKey(0) 
cv2.destroyAllWindows() 

Resultado:

detectados rectas que delimitan:

enter image description here

Luego, llene los rectángulos con esas negro:

enter image description here

Es mejor que el anterior, por supuesto, si usted no quiere "naranja")

+0

¿por qué cambiaste el tamaño de la imagen? – chostDevil

+0

Es porque su imagen es tan grande que mi pantalla no puede incluirla como un todo. (Aquí no es tan importante. Evítalo si no te gusta. "También imágenes más pequeñas significan operaciones más rápidas".) Por cierto, ¿qué método realmente querías? con NARANJA o sin NARANJA? –

+0

si conoce C++, actualice su respuesta ya que no puedo mapear entre python y C++ – chostDevil

1

Puede usar filtros morfológicos (tal vez alternando el filtrado secuencial) para simplificar su imagen multicolor y luego usar un algoritmo de segmentación como cuenca hidrográfica o algún método de granulometría y elegir el objeto más grande. Puede encontrar varias implementaciones en línea. Pero esto solo funcionará si el logotipo es discreto (por ejemplo, no en el fondo)

+0

¿qué es lo que quiere decir con (no en el fondo) – chostDevil

+0

@PatrickJones quiero decir si se trata de una imagen en alguna parte, y no uno de esas tarjetas de visita donde el logotipo está debajo del texto y ocupa toda la tarjeta. O si la tarjeta está dividida en varias regiones de color. Hay muchos casos – sivann

+0

¿Qué son los filtros morfológicos o el filtrado secuencial alterno? Por favor, consulte – chostDevil

Cuestiones relacionadas