Created
March 14, 2011 16:09
-
-
Save yvesf/869381 to your computer and use it in GitHub Desktop.
hugh-kram
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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