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[edit]

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.