web-dev-qa-db-de.com

wie erkennt man einen Bereich mit einer großen Anzahl weißer Pixel mit opencv?

ich möchte das Logo im Bild erkennen, um es zu entfernen. Ich habe die Idee, nach Objekten zu suchen, die die große Anzahl von Pixeln haben. Eine andere Idee ist, alle weißen Pixel durchzugehen (ich habe mein Bild invertiert) und Suchen Sie nach Pixeln, die einen großen Bereich bilden, und entfernen Sie diesen Bereich. Gibt es einen besseren Algorithmus als diesen? Auch welche Methoden in opencv helfen mir, Objekte mit einer großen Pixelanzahl zu erkennen?.

14
chostDevil

Ich habe eine Methode, um dies zu tun. Ich weiß nicht, ob diese Methode auf alle anwendbar ist, aber sie funktioniert hier gut.

Hier ist der Code (in Python):

Konvertieren Sie zunächst ein Bild in Graustufen, ändern Sie die Bildgröße, wenden Sie den Schwellenwert an, und erstellen Sie ein Maskenbild mit der gleichen Größe und dem gleichen Typ wie das Graustufenbild, dessen Größe geändert wurde. (Maskenbild ist nur ein schwarzes Bild)

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)

Finden Sie jetzt Konturen im Schwellwertbild. Filtern Sie die Kontur für eine Fläche zwischen 500 und 5000. Es handelt sich höchstwahrscheinlich um einen großen weißen Fleck, offensichtlich nicht um Buchstaben. (Denken Sie daran, dass dieser Bereich speziell für dieses Bild ist. Ich kenne Ihre anderen Bilder nicht. Sie müssen es selbst finden). Zeichnen Sie nun diese Kontur auf das mit weißer Farbe gefüllte Maskenbild.

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

Jetzt invertieren Sie das Bild mit der cv2.bitwise_not-Funktion. Dort haben Sie die Möglichkeit, eine Maske anzugeben, in der wir unser Maskenbild angeben, sodass die Funktion nur für den Bereich im Eingabebild gilt, in dem das Maskenbild weiß ist.

cv2.bitwise_not(gray2,gray2,mask)

Und endlich das Bild zeigen:

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

Und hier ist das Ergebnis:

enter image description here


HINWEIS:

Die obige Methode wird angewendet, um "ORANGE" im weißen Quadrat zu erhalten. Deshalb gibt es einige Artefakte. Wenn Sie diese Orange auch nicht möchten, kann sie genauer sein.

Suchen Sie einfach das Begrenzungsrechteck für die gefilterten Konturen und zeichnen Sie ein mit schwarzer Farbe gefülltes Rechteck.

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

Ergebnis:

erkannte Bounding-Rects:

enter image description here

Dann füllen Sie diese Rechtecke mit Schwarz aus:

enter image description here

Es ist besser als vorher, natürlich, wenn Sie nicht "ORANGE" wollen.

34
Abid Rahman K

Sie können morphologische Filter verwenden (möglicherweise alternierende sequentielle Filterung), um Ihr mehrfarbiges Bild zu vereinfachen, und dann einen Segmentierungsalgorithmus wie "Wasserscheide" oder eine andere Granulometriemethode verwenden und das größte Objekt auswählen. Sie können mehrere Implementierungen online finden. Dies funktioniert jedoch nur, wenn das Logo diskret ist (z. B. nicht im Hintergrund).

1
sivann