Mercurial > forge
changeset 1661:fbe90e63f657 octave-forge
Straight line Hough-transform
author | sjvdw |
---|---|
date | Fri, 20 Aug 2004 09:09:31 +0000 |
parents | 242f04cdb215 |
children | cf21a705b2e8 |
files | main/image/houghtf.cc |
diffstat | 1 files changed, 129 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/image/houghtf.cc Fri Aug 20 09:09:31 2004 +0000 @@ -0,0 +1,129 @@ +/* Copyright (C) 2004 Stefan van der Walt <stefan@sun.ac.za> + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +#include <octave/oct.h> + +DEFUN_DLD( houghtf, args, , "\ +\ +usage: [H, R] = houghtf(I[, angles])\n\ +\n\ + Calculate the straight line Hough transform of an image.\n\ +\n\ + The image, I, should be a binary image in [0,1]. The angles are given\n\ + in degrees and defaults to -90..90.\n\ +\n\ + H is the resulting transform, R the radial distances.\n\ +\n\ + See also: Digital Image Processing by Gonzales & Woods (2nd ed., p. 587)\n") { + + octave_value_list retval; + bool DEF_THETA = false; + + if (args.length() == 1) { + DEF_THETA = true; + } else if (args.length() != 2) { + print_usage("houghtf"); + return retval; + } + + Matrix I = args(0).matrix_value(); + + ColumnVector thetas = ColumnVector(); + if (!DEF_THETA) { + thetas = ColumnVector(args(1).vector_value()); + } else { + thetas = ColumnVector(Range(-90,90).matrix_value()); + } + + if (error_state) { + print_usage("houghtf"); + return retval; + } + + thetas = thetas / 180 * M_PI; + + int r = I.rows(); + int c = I.columns(); + + Matrix xMesh = Matrix(r, c); + Matrix yMesh = Matrix(r, c); + for (int m = 0; m < r; m++) { + for (int n = 0; n < c; n++) { + xMesh(m, n) = n+1; + yMesh(m, n) = m+1; + } + } + + Matrix size = Matrix(1, 2); + size(0) = r; size(1) = c; + double diag_length = sqrt( size.sumsq()(0) ); + int nr_bins = 2 * (int)ceil(diag_length) - 1; + RowVector bins = RowVector( Range(1, nr_bins).matrix_value() ) - (int)ceil(nr_bins/2); + + Matrix J = Matrix(bins.length(), 0); + + for (int i = 0; i < thetas.length(); i++) { + double theta = thetas(i); + ColumnVector rho_count = ColumnVector(bins.length(), 0); + + double cT = cos(theta); double sT = sin(theta); + for (int x = 0; x < r; x++) { + for (int y = 0; y < c; y++) { + if ( I(y, x) == 1 ) { + int rho = (int)round( cT*x + sT*y ); + int bin = (int)(rho - bins(0)); + if ( (bin > 0) && (bin < bins.length()) ) { + rho_count( bin )++; + } + } + } + } + + J = J.append( rho_count ); + } + + retval.append(J); + retval.append(bins); + return retval; + +} + +/* +%!test +%! I = zeros(100, 100); +%! I(1,1) = 1; I(100,100) = 1; I(1,100) = 1; I(100, 1) = 1; I(50,50) = 1; +%! [J, R] = houghtf(I); J = J / max(J(:)); +%! assert(size(J) == [length(R) 181]); +%! + +%!demo +%! I = zeros(100, 150); +%! I(30,:) = 1; I(:, 65) = 1; I(35:45, 35:50) = 1; +%! for i = 1:90, I(i,i) = 1;endfor +%! I = imnoise(I, 'salt & pepper'); +%! imshow(I); +%! J = houghtf(I); J = J / max(J(:)); +%! imshow(J, bone(128), 'truesize'); + +*/