jak wykryć region dużych # białych pikseli za pomocą opencv?
Chcę wykryć logo wewnątrz obrazu , aby go usunąć, mam pomysł, który jest szukać obiektów, które mają dużą liczbę pikseli, a następnie usunąć, innym pomysłem jest, aby pętli przez wszystkie białe piksele (mam odwrócony obraz) i szukać pikseli, które tworzą duży region, a następnie usunąć ten region, jest jakiś algorytm lepszy niż ten, również które metody w opencv pomogą mi wykryć obiekt o dużej liczbie pikseli.
2 answers
Mam na to sposób. Nie wiem, czy ta metoda ma zastosowanie do wszystkich, ale działa dobrze tutaj.
Poniżej znajduje się kod (w Pythonie):
Najpierw przekonwertuj obraz na skalę szarości, Zmień rozmiar obrazu, zastosuj próg i utwórz obraz maski o takim samym rozmiarze i typie, jak obraz w skali szarości. (Obraz maski jest tylko czarnym obrazem)
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)
Teraz znajdź kontury w obrazie progu. Filtruj kontur dla obszaru od 500 do 5000. Będzie to najprawdopodobniej duża biała plama, oczywiście nie listy. (Pamiętaj, ten obszar jest szczególny dla tego obrazu. Nie wiem o twoich innych zdjęciach. Będziesz musiał sam go znaleźć). Teraz narysuj ten kontur na obrazie maski wypełnionym białym kolorem.
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:
Next is the mask image:
Teraz odwracasz obraz za pomocą funkcji cv2.bitwise_not
. Tam masz możliwość podania maski, gdzie podajemy nasz obraz maski tak, że funkcja działa tylko na obszarze w obrazie wejściowym, gdzie jest biały w masce obraz.
cv2.bitwise_not(gray2,gray2,mask)
I na koniec Pokaż obrazek:
cv2.imshow('IMG',gray2)
cv2.waitKey(0)
cv2.destroyAllWindows()
A oto wynik:
Uwaga:
Powyższa metoda jest wykonywana w celu zachowania "pomarańczowego" w białym kwadracie. Dlatego są tam artefakty. Jeśli nie chcesz, że pomarańczowy również, może być bardziej dokładne.
Znajdź prostokąt obwiedni dla konturów filtrowanych powierzchniowo i narysuj prostokąt wypełniony czarnym kolorem.
Kod:
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()
Wynik:
Wykryto rect:
Następnie wypełnij te prostokąty czarnym:
Jest lepszy od poprzedniego , oczywiście jeśli nie chcesz "pomarańczowego")Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-22 10:23:20
Możesz użyć filtrów morfologicznych (być może naprzemienne filtrowanie sekwencyjne), aby uprościć wielobarwny obraz, a następnie użyć algorytmu segmentacji, takiego jak watershed lub jakaś metoda granulometrii i wybrać największy obiekt. Można znaleźć kilka wdrożeń online. Ale będzie to działać tylko wtedy, gdy logo jest dyskretne (np. nie na tle)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-21 20:21:42