web-dev-qa-db-fra.com

comment détecter une région de grand nombre de pixels blancs en utilisant opencv?

je veux détecter le logo dans l'image afin de l'enlever, j'ai une idée qui est de rechercher des objets qui ont le grand nombre de pixels, puis de les supprimer, une autre idée est de faire une boucle à travers tous les pixels blancs (j'ai inversé mon image) et cherchez des pixels qui forment une grande région, puis supprimez cette région, existe-t-il un algorithme meilleur que celui-ci, ainsi que les méthodes qui lui sont ouvertes pour m'aider à détecter les objets de grand nombre de pixels.

14
chostDevil

J'ai une méthode pour le faire. Je ne sais pas si cette méthode est applicable à tous, mais cela fonctionne bien ici.

Voici le code (en Python):

Convertissez d'abord l'image en niveaux de gris, redimensionnez l'image, appliquez le seuil et créez une image de masque de même taille et de même type que celle d'une image redimensionnée en niveaux de gris. (L'image du masque est juste une image noire)

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)

Maintenant, trouvez les contours dans l'image de seuil. Filtrez le contour pour les zones comprises entre 500 et 5 000. Il s'agira probablement d'une grosse goutte blanche, évidemment pas de lettres. (N'oubliez pas que cette zone est particulière pour cette image. Je ne connais pas vos autres images. Vous devrez la trouver vous-même). Dessinez maintenant ce contour sur l’image de masque remplie de couleur blanche.

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

Maintenant, vous inversez l'image à l'aide de la fonction cv2.bitwise_not. Là vous avez l'option pour donner le masque où nous donnons notre image de masque afin que cette fonction n'agisse que sur la zone de l'image d'entrée où il y a du blanc dans l'image du masque.

cv2.bitwise_not(gray2,gray2,mask)

Et enfin montrer l'image:

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

Et voici le résultat:

enter image description here


REMARQUE:

La méthode ci-dessus est faite pour conserver "ORANGE" dans un carré blanc. C'est pourquoi certains artefacts sont là. Si vous ne voulez pas que l'orange aussi, il peut être plus précis.

Il suffit de trouver le rectangle de délimitation pour les contours filtrés par surface et de dessiner un rectangle rempli de couleur noire.

Code:

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()

Résultat :

détecter les effets déterminants:

enter image description here

Puis remplissez ces rectangles de noir:

enter image description here

C'est mieux que les précédents, bien sûr si vous ne voulez pas "ORANGE")

34
Abid Rahman K

Vous pouvez utiliser des filtres morphologiques (par exemple, un filtrage séquentiel alternatif) pour simplifier votre image multicolore, puis utiliser un algorithme de segmentation tel que la méthode du bassin versant ou une méthode de granulométrie pour choisir le plus grand objet. Vous pouvez trouver plusieurs implémentations en ligne. Mais cela ne fonctionnera que si le logo est discret (par exemple, pas sur le fond)

1
sivann