PTdecode/CImg-1.3.0/examples/hough_transform.cpp

Fri, 25 Sep 2009 10:50:44 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Fri, 25 Sep 2009 10:50:44 +0100
changeset 21
629637abfe1f
parent 5
1204ebf9340d
permissions
-rwxr-xr-x

added dots-per-inch to status readback

     1 /*
     2  #
     3  #  File        : hough_transform.cpp
     4  #                ( C++ source file )
     5  #
     6  #  Description : Implementation of the Hough transform.
     7  #                This file is a part of the CImg Library project.
     8  #                ( http://cimg.sourceforge.net )
     9  #
    10  #  Copyright   : David Tschumperle
    11  #                ( http://www.greyc.ensicaen.fr/~dtschump/ )
    12  #
    13  #  License     : CeCILL v2.0
    14  #                ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html )
    15  #
    16  #  This software is governed by the CeCILL  license under French law and
    17  #  abiding by the rules of distribution of free software.  You can  use,
    18  #  modify and/ or redistribute the software under the terms of the CeCILL
    19  #  license as circulated by CEA, CNRS and INRIA at the following URL
    20  #  "http://www.cecill.info".
    21  #
    22  #  As a counterpart to the access to the source code and  rights to copy,
    23  #  modify and redistribute granted by the license, users are provided only
    24  #  with a limited warranty  and the software's author,  the holder of the
    25  #  economic rights,  and the successive licensors  have only  limited
    26  #  liability.
    27  #
    28  #  In this respect, the user's attention is drawn to the risks associated
    29  #  with loading,  using,  modifying and/or developing or reproducing the
    30  #  software by the user in light of its specific status of free software,
    31  #  that may mean  that it is complicated to manipulate,  and  that  also
    32  #  therefore means  that it is reserved for developers  and  experienced
    33  #  professionals having in-depth computer knowledge. Users are therefore
    34  #  encouraged to load and test the software's suitability as regards their
    35  #  requirements in conditions enabling the security of their systems and/or
    36  #  data to be ensured and,  more generally, to use and operate it in the
    37  #  same conditions as regards security.
    38  #
    39  #  The fact that you are presently reading this means that you have had
    40  #  knowledge of the CeCILL license and that you accept its terms.
    41  #
    42 */
    44 #include "CImg.h"
    45 using namespace cimg_library;
    47 // The lines below are necessary when using a non-standard compiler as visualcpp6.
    48 #ifdef cimg_use_visualcpp6
    49 #define std
    50 #endif
    51 #ifdef min
    52 #undef min
    53 #undef max
    54 #endif
    56 #ifndef cimg_imagepath
    57 #define cimg_imagepath "img/"
    58 #endif
    60 int main(int argc,char **argv) {
    62   cimg_usage("Illustration of the Hough transform");
    63   CImg<unsigned char> src(cimg_option("-i",cimg_imagepath "parrot_original.ppm","Input image"));
    64   CImg<> vote(500,400,1,1,0), img = CImg<>(src).get_pointwise_norm().normalize(0,255).resize(-100,-100,1,2,2);
    66   CImgDisplay disp(src,"Image"), dispvote(vote,"Hough Transform");
    67   const unsigned char col1[3]={255,255,255}, col2[3]={0,0,0};
    68   const double
    69     alpha = cimg_option("-a",1.5,"Gradient smoothing"),
    70     sigma = cimg_option("-s",0.5,"Hough Transform smoothing"),
    71     rhomax = std::sqrt((double)(img.dimx()*img.dimx()+img.dimy()*img.dimy()))/2,
    72     thetamax = 2*cimg::valuePI;
    74   if (cimg::dialog(cimg::basename(argv[0]),
    75                    "Instructions : \n"
    76                    "------------\n\n"
    77                    "(1) When clicking on the image, all lines crossing the point\n"
    78                    "will be voted in the Hough Transform image.\n\n"
    79                    "(2) When clicking on the vote image, the corresponding line is drawn\n"
    80                    "on the image.\n\n"
    81                    "(3) When pressing the space bar, the image lines are detected from the\n"
    82                    "image gradients.\n\n"
    83                    "Note that a logarithmic scaling is performed for the vote image display.\n"
    84                    "See also the available options (option '-h')\n","Start !","Quit",0,0,0,0,
    85                    src.get_resize(100,100,1,3),true)) std::exit(0);
    87   while (!disp.is_closed && !dispvote.is_closed && !disp.is_keyQ && !dispvote.is_keyQ && !disp.is_keyESC && !dispvote.is_keyESC) {
    89     CImgDisplay::wait(disp,dispvote);
    91     // When pressing space bar, the vote is performed from the image gradients.
    92     if (dispvote.key==cimg::keySPACE || disp.key==cimg::keySPACE) {
    93       CImgList<> grad = img.get_gradient();
    94       cimglist_for(grad,l) grad[l].blur((float)alpha);
    95       vote.fill(0);
    96       cimg_forXY(img,x,y) {
    97         const double
    98           X = (double)x-img.dimx()/2,
    99           Y = (double)y-img.dimy()/2,
   100           gx = grad[0](x,y),
   101           gy = grad[1](x,y);
   102         double
   103           theta = std::atan2(gy,gx),
   104           rho   = std::sqrt(X*X+Y*Y)*std::cos(std::atan2(Y,X)-theta);
   105         if (rho<0) { rho=-rho; theta+=cimg::valuePI; }
   106         theta = cimg::mod(theta,thetamax);
   107         vote((int)(theta*dispvote.dimx()/thetamax),(int)(rho*dispvote.dimy()/rhomax))+=(float)std::sqrt(gx*gx+gy*gy);
   108       }
   109       vote.blur((float)sigma);
   110       CImg<> vote2(vote); { cimg_forXY(vote2,x,y) vote2(x,y) = (float)std::log(1+vote(x,y)); vote2.display(dispvote); }
   111     }
   113      // When clicking on the vote window.
   114     if (dispvote.button) {
   115       const double
   116         rho   = dispvote.mouse_y*rhomax/dispvote.dimy(),
   117         theta = dispvote.mouse_x*thetamax/dispvote.dimx(),
   118         x = img.dimx()/2  + rho*std::cos(theta),
   119         y = img.dimy()/2 + rho*std::sin(theta);
   120       const int
   121         x0 = (int)(x+1000*std::sin(theta)),
   122         y0 = (int)(y-1000*std::cos(theta)),
   123         x1 = (int)(x-1000*std::sin(theta)),
   124         y1 = (int)(y+1000*std::cos(theta));
   125       CImg<unsigned char>(src).
   126         draw_line(x0,y0,x1,y1,col1,1.0f,0xF0F0F0F0).draw_line(x0,y0,x1,y1,col2,1.0f,0x0F0F0F0F).
   127         draw_line(x0+1,y0,x1+1,y1,col1,1.0f,0xF0F0F0F0).draw_line(x0+1,y0,x1+1,y1,col2,1.0f,0x0F0F0F0F).
   128         draw_line(x0,y0+1,x1,y1+1,col1,1.0f,0xF0F0F0F0).draw_line(x0,y0+1,x1,y1+1,col2,1.0f,0x0F0F0F0F).
   129         display(disp);
   130      }
   132      // When clicking on the image.
   133     if (disp.button && disp.mouse_x>=0) {
   134        const double
   135          x0 = (double)disp.mouse_x-disp.dimx()/2,
   136          y0 = (double)disp.mouse_y-disp.dimy()/2,
   137          rho0 = std::sqrt(x0*x0+y0*y0),
   138          theta0 = std::atan2(y0,x0);
   140        for (double t=0; t<thetamax; t+=0.001) {
   141          double theta = t, rho = rho0*std::cos(theta0-t);
   142          if (rho<0) { rho=-rho; theta=cimg::mod(theta+cimg::valuePI,thetamax); }
   143          vote((int)(theta*vote.dimx()/thetamax),(int)(rho*vote.dimy()/rhomax))+=1;
   144        }
   145        CImg<> vote2(vote); cimg_forXY(vote2,x,y) vote2(x,y) = (float)std::log(1+vote(x,y)); vote2.display(dispvote);
   146     }
   147     dispvote.resize(dispvote);
   148     disp.resize(disp);
   149   }
   151   std::exit(0);
   152   return 0;
   153 }