in Sachen Bildverarbeitung bin ich absolut kein Experte und benötige ein wenig Hilfe.
Quelle ist das Bild "img" (ohne den blauen Rahmen natürlich). Das Ziel ist es die position des schwarzen Kreises genau zu lokalisieren. Am besten den Mittelpunkt.
Lösen wollte ich das mit dem Mean-Shift Verfahren. Keine Ahnung ob das die beste Methode dafür ist. Ich kenne sie einfach schon grob.
Dazu wurde das Bild einmal in den HSV-Farbraum konvertiert. Auf dieser Grundlage konnte ich ein paar Rahmenbedingungen eingrenzen was Sättigung und Helligkeit angeht. Farbe kann ich nicht begrenzen, da nicht klar ist welchen Farbwert dieses fast schwarz letztendlich besitzt. Es ergibt sich "mask". Für das Mean-Shift ist aber noch ein BackProject nötig, von dem ich ganz ehrlich nicht ganz kappiere wofür es gut sein soll. Das ist dann in "dst" dargestellt. Nach dem Mean-Shift ergibt sich dann die Position von "img2". Diese ist aber nicht korrekt. Auch mit viel rumspielen gelingt es mir nicht eine sichere Positionsbestimmung zu machen.
Die Maske ist meiner Meinung nach garnicht so übel, aber dieses BackProjekt-Ergebnis ist irgendwie unschön. Was kann ich tun? Ist das Verfahren dafür gut geeignet oder könnt ihr bessere empfehlen?
Code: Alles auswählen
import cv2
import numpy as np
def main():
#Ausschnitt
r,h,c,w = 250,50,250,20
#Fenster
track_window = (c,r,w,h)
#Bild einlesen
img = cv2.imread('test.jpg')
img1 = cv2.rectangle(img.copy(), (r, c), (r+w, c+h), 255, 2)
cv2.imshow('img', img1)
#HSV konvertieren
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
cv2.imshow('hsv', hsv)
#Farben eingrenzen
mask = cv2.inRange(hsv, np.array((0., 10., 35.)), np.array((180., 60., 50.)))
cv2.imshow('mask', mask)
#Histogramm der Farbwerte
roi_hist = cv2.calcHist([hsv], [0], mask, [180], [0,180])
#Histogramm auf 0-255 normalisieren
cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)
#Terminierung von Mean-Shift
term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 100, 0.5)
dst = cv2.calcBackProject([hsv], [2], roi_hist, [0,255], 1)
cv2.imshow('dst', dst)
#_, contours, hierarchy = cv2.findContours(dst, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
#ret = cv2.contourArea(contours)
#dst1 = np.zeros((480,640,3),np.uint8)
#cv2.drawContours(dst1, contours, -1, [150, 255, 30], cv2.FILLED)
#cv2.imshow('dst2', dst1)
#Mean-Shift
ret, track_window = cv2.meanShift(dst, track_window, term_crit)
#
x,y,w,h = track_window
#Rechteck einzeichnen
img2 = cv2.rectangle(img, (x, y), (x+w, y+h), 255, 2)
cv2.imshow('img2', img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
return
if __name__ == '__main__':
main()