Jump to content

Example:Hough transform/Tcl

From Rosetta Code

This is a programming example for the Hough transform programming task. If the task description is not listed here, refer back to that page.


package require Tk

set PI 3.1415927
proc HoughTransform {src trg {fieldColor "#000000"}} {
    global PI

    set w [image width $src]
    set h [image height $src]
    set targetH [expr {int(hypot($w, $h)/2)}]

    # Configure the target buffer
    $trg configure -width 360 -height $targetH
    $trg put $fieldColor -to 0 0 359 [expr {$targetH-1}]

    # Iterate over the target's space of pixels.
    for {set rho 0} {$rho < $targetH} {incr rho} {
	set row {}
	for {set theta 0} {$theta < 360} {incr theta} {
	    set cos [expr {cos($theta/180.0*$PI)}]
	    set sin [expr {sin($theta/180.0*$PI)}]
	    set totalRed 0
	    set totalGreen 0
	    set totalBlue 0
	    set totalPix 0

	    # Sum the colors of the line with equation x*cos(θ) + y*sin(θ) = ρ
	    if {$theta<45 || ($theta>135 && $theta<225) || $theta>315} {
		# For these half-quadrants, it's better to iterate by 'y'
		for {set y 0} {$y<$h} {incr y} {
		    set x [expr {
			$w/2 + ($rho - ($h/2-$y)*$sin)/$cos
		    }]
		    if {$x < 0 || $x >= $w} continue
		    set x [expr {round($x)}]
		    if {$x == $w} continue
		    incr totalPix
		    lassign [$src get $x $y] r g b
		    incr totalRed $r
		    incr totalGreen $g
		    incr totalBlue $b
		}
	    } else {
		# For the other half-quadrants, it's better to iterate by 'x'
		for {set x 0} {$x<$w} {incr x} {
		    set y [expr {
			$h/2 - ($rho - ($x-$w/2)*$cos)/$sin
		    }]
		    if {$y < 0 || $y >= $h} continue
		    set y [expr {round($y)}]
		    if {$y == $h} continue
		    incr totalPix
		    lassign [$src get $x $y] r g b
		    incr totalRed $r
		    incr totalGreen $g
		    incr totalBlue $b
		}
	    }

	    # Convert the summed colors back into a pixel for insertion into
	    # the target buffer.
	    if {$totalPix > 0} {
		set totalPix [expr {double($totalPix)}]
		set col [format "#%02x%02x%02x" \
			[expr {round($totalRed/$totalPix)}] \
			[expr {round($totalGreen/$totalPix)}] \
			[expr {round($totalBlue/$totalPix)}]]
	    } else {
		set col $fieldColor
	    }
	    lappend row $col
	}
	$trg put [list $row] -to 0 $rho
    }
}

Demonstration Code

Takes the name of the image to apply the transform to as an argument. If using PNG images,

Works with: Tk version 8.6

or TkImg

# Demonstration code
if {[catch {
    package require Tk 8.6; # Just for PNG format handler
}] == 1} then {catch {
    package require Img
}}
# If neither Tk8.6 nor Img, then only GIF and PPM images can be loaded

set f [lindex $argv 0]
image create photo srcImg -file $f
image create photo targetImg
pack [labelframe .l1 -text Source] [labelframe .l2 -text Target]
pack [label .l1.i -image srcImg]
pack [label .l2.i -image targetImg]
# Postpone until after we've drawn ourselves
after idle HoughTransform srcImg targetImg [lrange $argv 1 end]
Image produced by Tcl implementation of the Hough transform when applied to the sample pentagon image.


Cookies help us deliver our services. By using our services, you agree to our use of cookies.