Skip to content

Instantly share code, notes, and snippets.

@yvesf
Created March 14, 2011 16:09
Show Gist options
  • Select an option

  • Save yvesf/869381 to your computer and use it in GitHub Desktop.

Select an option

Save yvesf/869381 to your computer and use it in GitHub Desktop.
hugh-kram
#coding: utf8
import image
import numpy as np
def hough(img,activation=None,edges=8,debug=None):
"""
Berechnet die Hough-Transformation für ein Bild.
Es wird parallel zum Bildraum ein 2-dimensionaler
Parameterraum angelegt ("hough_raum") mithilfe dessen
alle möglichen Geraden bewertet werden.
Im nächsten Schritt die weniger wahrscheinlichen
Geraden "aussortiert" (Felder zurückgesetzt). Es werden
bis zu I{edges} der Anzahl geraden ausgewählt.
Aus praktischen Gründen wird mit der Hessischen
Normalform einer Gleichung gerechnet:
M{x*sin(S{theta}) + y*cos(S{theta}) = -r}
Parameterraum::
^ S{theta}
3.14/180 |
|
|
0/0 +--------------> r
@type img: image.Image
@param img: Möglichst vor-segmentiertes Bild in
dem Kanten erkannt werden sollen.
@type activation: function
@param activation: Eine Funktion (bzw. Lambda) der
x,y und der Bildwert übergeben wird.
Gibt sie B{wahr} zurück, dann wird dieser
Pixel von der Hough-Transformation berücksichtigt.
(Default: alle nicht weissen (value==255) Punkte werden
erkannt, C{lambda x,y,value: value != 255}).
@type edges: int
@param edges: Anzahl der zu suchenden Kanten
@type debug: function
@param debug: Funktion zur Ausgabe von Debugmeldungen (Default print)
@return None
"""
# Standardoperationen
activation = activation or (lambda x,y,value: value != 255)
def do_print(msg):
print msg
debug = debug or do_print
# Wertebereich von r bestimmen
min_r = 0
max_r = np.sqrt( (img.width)**2 + (img.height)**2 )
debug("max_r={max_r} min_r={min_r}".format(max_r=max_r, min_r=min_r))
# Initialisieren des Parameterraum mit 0
hough_raum = np.array([ np.arange(int(min_r),int(max_r+1)) for z in range(0, 180)])
hough_raum.fill(0)
# Berechnen des Parameterraum
for x,y,value in img:
# Testen ob Pixel ein Eckpunkt darstellt
if not activation(x,y,value):
continue
for grad in range(0,180):
theta = np.deg2rad(grad)
r = x * np.cos(theta) + y * np.sin(theta)
if r >= min_r and r <= max_r:
hough_raum[grad][int(r)] += 1
debug("hough_raum berechnet")
# Schwellwert bestimmen
sorted = list(hough_raum.flat)
sorted.sort()
schwelle = sorted[-edges]
debug("schwelle={schwelle}".format(schwelle=schwelle))
# Einzeichnen der gewonnen Geraden
draw = image.Draw(img)
for grad in range(1,180):
theta = np.deg2rad(grad)
for r in range(int(min_r),int(max_r+1)):
if hough_raum[grad][r] < schwelle:
continue
x0, x1 = 0, img.width-1
# Berechnen der Y-Koordinaten
y0 = ( -np.cos(theta)/np.sin(theta) ) * x0 + r/np.sin(theta)
y1 = ( -np.cos(theta)/np.sin(theta) ) * x1 + r/np.sin(theta)
debug("akku={akku} r={r} theta={theta} p1=({x0},{y0}) p2=({x1},{y1})".format(
akku=hough_raum[grad][r], r=r, theta=theta, x0=x0, y0=y0, x1=x1, y1=y1))
y0,y1 = int(y0), int(y1)
draw.line(x2, y0, x1, y1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment