Seite 1 von 1
Kantenerkennung mit Canny-Algorithmus! Problem bei den Ecken
Verfasst: Donnerstag 24. April 2014, 12:40
von kl.feigling89
Hallo, ich habe ein sehr großes Problem. Ich möchte die Kanten eines Bildes detektieren und benutze dafür den Canny-Algorithmus der OpenCV Library. Leider verursacht der Algorithmus ein paar Fehler:
Bei einem Rechteck werden die beiden linken Randpixel nicht gezeichnet.
Code: Alles auswählen
def getEdgeImage(image,threshold1,threshold2):
edgeImage = cv2.Canny(image,threshold1,threshold2)
return edgeImage
Hier einmal ein kleines beispiel: x soll das Rechteck darstellen und 0 der Hintergrund
Originalbild
Code: Alles auswählen
00000000000
00000000000
000xxxxxx000
000xxxxxx000
000xxxxxx000
00000000000
So solte es aussehen :
Code: Alles auswählen
000000000000
00xxxxxxxx000
00x00000x000
00x00000x000
00x00000x000
00xxxxxxxx000
Bei mir sieht es aber so aus:
Code: Alles auswählen
000000000000
000xxxxxxx000
00x00000x000
00x00000x000
00x00000x000
000xxxxxxx000
Habe ich was falsch gemacht? oder kann der Canny-Algorithmus die Ecke nicht sauber ? oder gibt es noch eine alternative?
Hoffe ihr könnt mir Helfen....
Re: Kantenerkennung mit Canny-Algorithmus! Problem bei den E
Verfasst: Freitag 25. April 2014, 09:08
von Sr4l
Wie wär's mit echten Beispielen und echten Bildern?
OpenCV hat auch noch den Sobel Operator und den LaPlace Filter implementiert.
Re: Kantenerkennung mit Canny-Algorithmus! Problem bei den E
Verfasst: Freitag 25. April 2014, 13:44
von kl.feigling89
So hier ein Beispiel:
Das Original Bild:

Hier nochmal eine vergrößerung:

und hier die Kante:
Deutlich zuerkennen das es nicht richtig passt.
Threshold1 =1
Threshold2 =255
Re: Kantenerkennung mit Canny-Algorithmus! Problem bei den E
Verfasst: Samstag 26. April 2014, 11:29
von anogayales
Zeig doch mal deinen Beispielcode! Das wäre für mich die offensichtliche Fehlerquelle.
Grüße,
anogayales
Re: Kantenerkennung mit Canny-Algorithmus! Problem bei den E
Verfasst: Montag 28. April 2014, 07:56
von kl.feigling89
Also ich habe folgenden Code:
Code: Alles auswählen
import cv2
threshold1 = 1
threshold2 = 255
path = 'test88.bmp'
image = cv2.imread(path,-1)
b,g,r = cv2.split(image)
edgeImage = cv2.Canny(b,threshold1,threshold2)
cv2.imwrite('edgeImage.png',edgeImage)
Re: Kantenerkennung mit Canny-Algorithmus! Problem bei den E
Verfasst: Dienstag 29. April 2014, 16:15
von Sr4l
War mir vorher auch nicht bewusst, aber der Canny Filter hat ein Problem mit "perfekten" Kanten zumindest wenn es es sich im Pixel bereich anschaut. Für die Bildverarbeitung von Kameras spielt das allerdings keine Rolle.
Hier ein Beispiel:
Code: Alles auswählen
import cv2
import numpy as np
#the image
img = np.ones([10,10])
img[3:7, 3:7] = 255
print "Image:"
print img
blur_img = cv2.GaussianBlur(img, (3,3), 0)
print
print "Blur:"
print blur_img.astype(np.int)
detected_edges = cv2.Canny(img.astype(np.uint8), 0, 0)
print
print "Canny without blur:"
print detected_edges.astype(np.int)
detected_edges = cv2.Canny(blur_img.astype(np.uint8), 0, 0)
print
print "Canny with blur:"
print detected_edges.astype(np.int)
from scipy import ndimage
sx = ndimage.sobel(img, axis=0, mode='constant')
sy = ndimage.sobel(img, axis=1, mode='constant')
sob = np.hypot(sx, sy)
print
print "Sobel:"
print sob.astype(np.int)
Output:
Code: Alles auswählen
Image:
[[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[ 1. 1. 1. 255. 255. 255. 255. 1. 1. 1.]
[ 1. 1. 1. 255. 255. 255. 255. 1. 1. 1.]
[ 1. 1. 1. 255. 255. 255. 255. 1. 1. 1.]
[ 1. 1. 1. 255. 255. 255. 255. 1. 1. 1.]
[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]
Blur:
[[ 1 1 1 1 1 1 1 1 1 1]
[ 1 1 1 1 1 1 1 1 1 1]
[ 1 1 16 48 64 64 48 16 1 1]
[ 1 1 48 143 191 191 143 48 1 1]
[ 1 1 64 191 255 255 191 64 1 1]
[ 1 1 64 191 255 255 191 64 1 1]
[ 1 1 48 143 191 191 143 48 1 1]
[ 1 1 16 48 64 64 48 16 1 1]
[ 1 1 1 1 1 1 1 1 1 1]
[ 1 1 1 1 1 1 1 1 1 1]]
Canny without blur:
[[ 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 255 255 0 0 0 0]
[ 0 0 0 255 0 0 255 0 0 0]
[ 0 0 255 0 0 0 255 0 0 0]
[ 0 0 255 0 0 0 255 0 0 0]
[ 0 0 0 255 255 255 255 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0]]
Canny with blur:
[[ 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 255 255 255 255 0 0 0]
[ 0 0 0 255 0 0 255 0 0 0]
[ 0 0 0 255 0 0 255 0 0 0]
[ 0 0 0 255 255 255 255 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0]]
Sobel:
[[ 4 4 4 4 4 4 4 4 4 4]
[ 4 0 0 0 0 0 0 0 0 4]
[ 4 0 359 803 1016 1016 803 359 0 4]
[ 4 0 803 1077 1016 1016 1077 803 0 4]
[ 4 0 1016 1016 0 0 1016 1016 0 4]
[ 4 0 1016 1016 0 0 1016 1016 0 4]
[ 4 0 803 1077 1016 1016 1077 803 0 4]
[ 4 0 359 803 1016 1016 803 359 0 4]
[ 4 0 0 0 0 0 0 0 0 4]
[ 4 4 4 4 4 4 4 4 4 4]]
Re: Kantenerkennung mit Canny-Algorithmus! Problem bei den E
Verfasst: Mittwoch 30. April 2014, 06:41
von kl.feigling89
Danke für deine Hilfe, leider weiß ich immer noch nicht genau wie ich mein Problem der Kantenerkennung am besten lösen kann. Wenn ich dein Verfahren mit dem Weichzeichnen benutze kann es zu fehlern kommen, wenn sich das Objekt zu nah am Rand des Bildes befindet. Gibt es noch eine andere Lösung die dieses Problem nicht hat? oder kann man das noch mit einem Trick lösen?
Code: Alles auswählen
import cv2
import numpy as np
#the image
img = np.zeros([8,8])
img[3:7, 3:7] = 255
print "Image:"
print img
blur_img = cv2.GaussianBlur(img, (3,3), 0)
print
print "Blur:"
print blur_img.astype(np.int)
detected_edges = cv2.Canny(img.astype(np.uint8), 0, 0)
print
print "Canny without blur:"
print detected_edges.astype(np.int)
detected_edges = cv2.Canny(blur_img.astype(np.uint8), 0, 0)
print
print "Canny with blur:"
print detected_edges.astype(np.int)
Ausgabe mit Fehler:

Re: Kantenerkennung mit Canny-Algorithmus! Problem bei den E
Verfasst: Mittwoch 30. April 2014, 22:16
von Sr4l
Auch das ist wieder etwas was einen bei Bildern mit hohen Auflösungen und dem "wichtigen" in der Mitte nicht interessiert. Falls du ein einheitlichen Hintergrund hast kannst du deine Bildfläche um diesen Erweitern.
Möglicherweise (wahrscheinlich) gibt es dafür eine Numpy Funktion, allerdings kenne ich keine und habe gerade keine Lust zum suchen aber das köntnest du in etwa so machen:
Code: Alles auswählen
import numpy as np
img = np.zeros([8,8])
img[3:7, 3:7] = 255
bigger_img = np.zeros([10,10])
bigger_img[:,:] = 5 # beispiel hintergrund farbe
bigger_img[1:9, 1:9] = img #einfuegen des original bilds
Für nicht einheitliche Hintergründe fällt mir keine Lösung ein.