head	1.5;
access;
symbols;
locks; strict;
comment	@ * @;


1.5
date	95.01.31.07.15.31;	author rjj;	state Exp;
branches;
next	1.4;

1.4
date	95.01.19.22.32.35;	author rjj;	state Exp;
branches;
next	1.3;

1.3
date	94.08.29.02.47.48;	author rjj;	state Exp;
branches;
next	1.2;

1.2
date	94.07.23.02.51.05;	author rjj;	state Exp;
branches;
next	1.1;

1.1
date	94.07.19.04.17.11;	author rjj;	state Exp;
branches;
next	;


desc
@Initial version that takes the output of test-hough and finds
  the points associated with maximum image values.
  A plot routine would be nice.
@


1.5
log
@Changed the name from  find-lines  to  hough-inverse because
  this verison attempts to calculate the inverse by using the
  reverse template operation and information contained in the
  accumulator image produced by the Hough transform.
@
text
@// hough-inverse.c      Section: 10.3, Line Detection using the Hough Transform
//      Copyright 1994, Center for Computer Vision and Visualization,
//      University of Florida.  All rights reserved.
//
// Use the left-template-product to calculate the inverse of the hough image.


#include "DDTempl.h"
#include "UcharConv.h"
#include "hough.h"
#include "find-max-points.h"

// Try to calculate the inverse image, which should sort of show
//   the lines identified by the Hough transform.
IA_Image<IA_Point<int>,u_char>
hough_inverse( const IA_Image<IA_Point<int>,IA_Bit> & in_image,
	       const IA_Image<IA_Point<int>,int> & accumulator,
	       const IA_Set<IA_Point<int> > & line_set )
{
    // Build the Hough Template associated with the input image.
    // NOTE:
    //  The HoughTemplate always supplies 2*positive_rows_request + 1
    //     rows and exactly the number of colums.  Hence the row count
    //     is always odd.  Since we are given the accumulator image,
    //     it should have an odd number of rows.
    IA_Point<int>
	rho( accumulator.domain().sup() - accumulator.domain().inf() );
    int ROWS( rho(0) / 2 ),   // Request only the positive rows
	COLS( rho(1) + 1 );   // Exactly the number of colums to request

    IA_DDTemplate<IA_Image<IA_Point<int>,u_char> >
	ht( HoughTemplate( in_image, ROWS, COLS ) );

    // The  lines  image will have 1 at each point where we want
    //   to find a line.
    IA_Image<IA_Point<int>,u_char>
	lines( accumulator.domain(), u_char( 0 ) ),
	where( line_set, u_char( 1 ) );

    lines.restrict_assign( where );

    return
	linear_product( ht, lines, in_image.domain() );
}



int main(int argc, char *argv[]) {

    // We accept 3 arguments
    // 1st arg: Hough input image
    // 2nd arg: Hough accumulator image (output of test-hough)
    // 3rd arg: NUM_TO_FIND,   default = 5

    if ( argc < 2 ) {
	cerr << "\nUsage: "
	     << "\n\t" << argv[0]
	     << " in.pgm in.accum.pgm [num-lines-to-find=5] > lines.pgm"
	     << endl;
	return 1;
    }

    unsigned int NUM_TO_FIND, i_arg;

    IA_Image<IA_Point<int>,IA_Bit>
	in_image( to_bit( read_uchar_PGM( argv[1] ) ) );

    IA_Image<IA_Point<int>,int>
	accum_image( read_int_PGM( argv[2] ) );

    i_arg   = ( argc > 3 ? atoi(argv[3]) : 0 );
    NUM_TO_FIND = ( i_arg > 1 ? i_arg : 5 );

    cerr << "Finding lines...";  cerr.flush();
    IA_Set<IA_Point<int> >
	lines = find_max_points( accum_image, NUM_TO_FIND );
    cerr << "done. Found: " << NUM_TO_FIND << " lines." << endl;


    cerr << "\nCalculating the Hough inverse image...." << endl;

    IA_Image<IA_Point<int>,u_char>
	inverse_hough_image(
	    hough_inverse(
		in_image,
		accum_image,
		lines )
	    );
    inverse_hough_image.write_PGM( cout );

    cerr << "done." << endl;

    return 0;
}
@


1.4
log
@Added standard header, changed exit() to return.
@
text
@d1 1
a1 1
// find-lines.c         Section: 10.3, Line Detection using the Hough Transform
d5 1
a5 2
// Assuming we have Hough image as input, find the number of lines
//    requested.
d7 1
a7 2
#include "IntPS.h"
#include "PSIter.h"
a46 30
void
table( const IA_Image<IA_Point<int>,int> & hough,
       const IA_Set<IA_Point<int> > & lines,
       ostream & outs,
       double R )
{
    // Lets create a little table for output
    // row column  count  rho  <rad  <deg

    IA_PSIter<IA_Point<int> > iter( lines );

    IA_Point<int> h_sup( hough.domain().sup() ), lp;
    double rows = h_sup(0), cols = h_sup(1);

    outs << "   Row    Col  Count        rho    theta-r    theta-d" << endl;
    while( iter( lp ) ) {
	int val = hough( lp );
	double row = lp(0), col = lp(1);
	double
	    theta = M_PI * col / cols,
	    rho   = 2*R  * row / rows - R;
	outs.width(6);  outs << int( row ) << " ";
	outs.width(6);  outs << int( col ) << " ";
	outs.width(6);  outs << val << " ";
	outs.width(10); outs << rho << " ";
	outs.width(10); outs << theta << " ";
	outs.width(10); outs << theta*180.0/M_PI << endl;
    }
}

d58 2
a59 1
	     << " in.pgm accum.pgm  [num-lines-to-find=5] > lines.pgm" << endl;
@


1.3
log
@Modified includes to be iac++ 2.0 compliant.
NOTE: This file is undergoing significant restructuring, I'm only checking
      it in to make sure I don't inadvertently delete it.
@
text
@d1 1
a1 1
// find-lines.c         Section: 10.3
d4 1
a7 1

d91 1
a91 1
	exit( 1 );
d124 1
a124 1
    exit( 0 );
@


1.2
log
@Checking in this version before adding additional functionality that
  will calculate the 'reverse' hough, to see what lines were found.
@
text
@d8 1
a8 1
#include "IntPointSet.h"
d10 2
d15 63
a78 1
void main(int argc, char *argv[]) {
d80 2
d83 2
a84 2
    // 1st arg: Hough image input rows
    // 2nd arg: Hough image input colums
d90 1
a90 1
	     << " rows cols  [num-lines-to-find=5] < accumulator.pgm" << endl;
d94 4
a97 1
    unsigned int hRows, hCols, NUM_TO_FIND, i_arg;
d99 2
a100 3
    hRows = atoi(argv[1]);
    hCols = atoi(argv[2]);
    double R( sqrt( hRows*hRows + hCols*hCols ) );
a104 3
    IA_Image<IA_Point<int>,int>
	hough( ( read_int_PGM(cin) ) );

d107 1
a107 1
	lines = find_max_points( hough, NUM_TO_FIND );
d110 2
a111 2
    // Lets create a little table for output
    // row column  count  rho  <rad  <deg
d113 8
a120 1
    IA_PSIter<IA_Point<int> > iter( lines );
d122 1
a122 2
    IA_Point<int> h_sup( hough.domain().sup() ), lp;
    double rows = h_sup(0), cols = h_sup(1);
d124 1
a124 14
    cout << "   Row    Col  Count        rho    theta-r    theta-d" << endl;
    while( iter( lp ) ) {
	int val = hough( lp );
	double row = lp(0), col = lp(1);
	double
	    theta = M_PI * col / cols,
	    rho   = 2*R  * row / rows - R;
	cout.width(6);  cout << int( row ) << " ";
	cout.width(6);  cout << int( col ) << " ";
	cout.width(6);  cout << val << " ";
	cout.width(10); cout << rho << " ";
	cout.width(10); cout << theta << " ";
	cout.width(10); cout << theta*180.0/M_PI << endl;
    }
@


1.1
log
@Initial revision
@
text
@d7 1
a7 1
//#include <iostream.h>
d10 2
a11 52
#include "BitDI.h"
#include "UcharDI.h"
#include "IntDI.h"


// This routine may find a few more lines than asked because
//    it extracts the max image value at each iteration, and
//    then adds all points associated with that value.
// Hence it is possible to get more than you ask for.
IA_Set<IA_Point<int> >
find_lines( const IA_Image<IA_Point<int>,int> & hough_image,
	    unsigned int & number_of_lines_to_find ) {

    int hMin = min( hough_image );
    if ( hMin < 0 ) {
	// A Hough image should always have values >= 0
	ia_throw( IA::INVALID_OPERATION, __FILE__, __LINE__ );
    }


    IA_Image<IA_Point<int>,u_char>
	chigt( chi_gt( hough_image, 0 ) );
    int max_to_be_found = sum( chigt );  // Can not sum( BDI )

    if ( max_to_be_found < number_of_lines_to_find ) {
	number_of_lines_to_find = max_to_be_found;
	// We can calculate this directly here.
	return
	    chigt.restrict( IA_Set<u_char>( u_char( 1 ) ) ).domain();
    }

    int found = 0;
    IA_Set<int> vs( hough_image.range() );
    IA_Set<IA_Point<int> > result( IA_empty_ipset( 2 ) );

    while( ( ! vs.empty() ) &&
	   ( found < number_of_lines_to_find ) ) {
	int maxval = vs.max();
	vs = vs / maxval;               // No  vs /= maxval;
	IA_Set<int> maxvs( maxval );

	// There are points to add to the result;
	IA_Set<IA_Point<int> >
	    maxips( hough_image.restrict( maxvs ).domain() );

	result |= maxips;
	found += maxips.card();
    }

    number_of_lines_to_find = found;
    return result;
}
d42 1
a42 1
	lines = find_lines( hough, NUM_TO_FIND );
@
