From cc1af1bcc5cbe79fd89404353efc29335184d81a Mon Sep 17 00:00:00 2001
From: ariotte <ariotte@PC-EII16.admr.insa>
Date: Fri, 20 Jul 2018 16:04:58 +0200
Subject: [PATCH] changed axis in hough transform

---
 app/Operations/Transforms.cpp | 132 +++++++++++++++-------------------
 1 file changed, 59 insertions(+), 73 deletions(-)

diff --git a/app/Operations/Transforms.cpp b/app/Operations/Transforms.cpp
index ba07feb..244a120 100644
--- a/app/Operations/Transforms.cpp
+++ b/app/Operations/Transforms.cpp
@@ -24,6 +24,7 @@
 #include <cstdlib>
 #include <cstdio>
 #include <Converter.h>
+#include <iostream>
 
 #include <Utilities/Log.h>
 using namespace std;
@@ -36,7 +37,7 @@ Image_t<double>* Transforms::hough(const GrayscaleImage *image ) {   //TODO : in
 
     double diag = sqrt(image->getWidth()*image->getWidth() + image->getHeight()*image->getHeight());
     
-    Image_t<double>* resImg = new Image_t<double>(diag+0.5, 90+180, 1, 0.);
+    Image_t<double>* resImg = new Image_t<double>(181, 2*diag + 1, 1, 0.);
 
     for(unsigned int i = 0; i < image->getHeight(); i++) {
         for(unsigned int j = 0; j < image->getWidth(); j++) {
@@ -52,61 +53,61 @@ Image_t<double>* Transforms::hough(const GrayscaleImage *image ) {   //TODO : in
                         }
 
                         if(image->getPixelAt(j1, i1) == 255) {
+                            /* Origine en bas à gauche x horizontale y verticale 
                             const double x0 = j;
                             const double y0 = image->getHeight()-i;//-i
                             const double x1 = j1;
                             const double y1 = image->getHeight()-i1;//-i1
+                            */
+                           /* Origine en haut à gauche x verticale y horizontale */
+                            const double x0 = i;
+                            const double y0 = j;
+                            const double x1 = i1;
+                            const double y1 = j1;
+                
+
                             const double l0 = sqrt((double)((y0-y1)*(y0-y1) + (x0-x1)*(x0-x1)));
                             const double l1 = fabs((double)(x0*y1 - x1*y0));
-                            const double rho = l1/l0; //Rho reel
+                            double rho = l1/l0; //Rho reel
                             double theta;// theta radian
                             double thetadeg;//theta degre
                             if(x0==x1){
                                 theta = 0;
-                                //Log::info("x0==x1");
 
                             }else{
                                 theta = atan((y1-y0) / (x1-x0))+ pid2;
-                                //Log::info("x0!=x1");
 
                                 //cas ou theta entre 0 et -pi/2
                                 //Calcul de l'ordonnee a l'origine
                                 int ordorig = y0 - x0 * ((y1-y0) / (x1-x0));
-                                //Log::info("theta = "+std::to_string(theta)+"atan = "+std::to_string(atan((y1-y0) / (x1-x0))+pid2)+ " ; ordorig = "+std::to_string(ordorig));
                                 if(ordorig < 0 && ((y1-y0) / (x1-x0)) > 0) theta = theta - pi;
                             }
                             //Passage de radian a degre
                             thetadeg = theta*(180/pi);
 
-//                            y2 = x1 != x0 ? atan((y1-y0) / (x1-x0))+ pid2 : y1 > y0 ? pi : pid2;//pid2 dans les deux cas (?)
-//                            theta = (int)(180-((y2 / pi) * 180. +180 + 0.5)) +1;//conversion en entier + modulo 180
-                            //theta = (int) ((y2/pi)*180);
-
 
                             //Coordonées du point a colorier dans l'espace de Hough
                             //Espace de Hough :
-                            //Origine en bas a gauche
-                            //Rho horizontal vers la droite de 0 a imageDiag
-                            //Theta vertical vers le haut de -90 a 180
+                            //Origine au centre
+                            //Rho vertical vers la droite de -imageDiag a imageDiag
+                            //Theta horizontale vers le haut de -90 à 90
                             int rhoStep = 1;
                             int angleStep = 1;
-                            int jDisplayRho = round(rho / rhoStep);
-                            int iDisplayTheta = round((180-thetadeg) / angleStep);
-                            //Log::info("x0 = "+std::to_string(x0)+ "; x1 = "+std::to_string(x1)+" ; y0 = "+std::to_string(y0)+" ; y1 = "+std::to_string(y1)+" ; Rho = "+std::to_string(rho)+" ; Theta = "+std::to_string(thetadeg)+" ; ThetaDisplay = "+std::to_string(iDisplayTheta));
-
-                            resImg->pixelAt(jDisplayRho, iDisplayTheta, 0)++;
-//                          resImg->setPixelAt(jDisplayRho, iDisplayTheta, resImg->getPixelAt(jDisplayRho, iDisplayTheta) + 1.);
+                            if(thetadeg > 90){
+                                thetadeg = thetadeg - 180;
+                                rho = -rho;
+                            }
+                            int jDisplayRho = round(( rho + diag )/ rhoStep) ;
+                            int iDisplayTheta = round((thetadeg + 90 ) / angleStep);
+                            
 
-                            //resImg->setPixelAt(j2, theta, resImg->getPixelAt(j2, theta) + 1.);
+                            resImg->pixelAt(iDisplayTheta, jDisplayRho, 0)++;
                         }
                     }
                 }
             }
         }
     }
-//    Image_t<double> *returnval = new Image_t<double>(width, height, 1, itab);
-//    delete itab;
-//    return returnval;
     return resImg;
 
 }
@@ -114,65 +115,56 @@ Image_t<double>* Transforms::hough(const GrayscaleImage *image ) {   //TODO : in
 
 Image_t<double>* Transforms::hough2(const Image *image, double angleStep, double rhoStep) {
 
-//    double angleStep = .5;
-//    double rhoStep = 1.;
-
-
-//    double imageDiag = image->getWidth() * sqrt(2.);
     double imageDiag = sqrt(image->getWidth()*image->getWidth() + image->getHeight()*image->getHeight());
-    Image_t<double>* resImg = new Image_t<double>(1. + imageDiag / rhoStep, (180.+90) / angleStep + 0.5, image->getNbChannels(), 0.);
+    Image_t<double>* resImg = new Image_t<double>( 181 / angleStep, (1. + imageDiag * 2) / rhoStep, image->getNbChannels(), 0.);
 
 
-    for(unsigned int c = 0; c < image->getNbChannels(); ++c) {
+    for(unsigned int c = 0; c < image->getNbChannels(); c++) {
 
-        for(unsigned int i = 0; i < image->getHeight(); ++i) // on parcourt l'image
+        for(unsigned int i = 0; i < image->getHeight(); i++) // on parcourt l'image
         {
-            for(unsigned int j = 0; j < image->getWidth(); ++j)
+            for(unsigned int j = 0; j < image->getWidth(); j++)
             {
                 if(image->getPixelAt(j, i, c) == 255)//getPixelAt demande la colonne j puis la ligne i
                 {
-                    //Changement de repere : origine en bas  a gauche de l'image, x horizontal vers la droite et y vertical vers le haut
-                    int x = j;
-                    int y = image->getHeight()-i;
+                    //Changement de repere : origine en haut  a gauche de l'image, x vertical vers le base et y horizontale vers la droite
+                    int x = i;
+                    int y = j;
                     //Parcours de tous les angles possibles dans l'image
-                    for(double te=-90; te < 180; te += angleStep) // on parcourt la matrice
+                    for(double te=-90; te <= 180; te += angleStep) // on parcourt la matrice
                     {
                         const double coste = cos(te * pi / 180.);
                         double sinte = sin(te * pi / 180.);
 
                         //Calcul de rho pour l'angle courant
-                        const double rho = x * coste + y * sinte;
+                        double rho = x * coste + y * sinte;
 
                         if(rho >= 0. && rho < imageDiag)
                         {
-                           // resImg->pixelAt(rho / rhoStep + 0.5, (resImg->getHeight()-(te+90)) / angleStep + 0.5, c)++;
                             //Coordonées du point a colorier dans l'espace de Hough
                             //Espace de Hough :
-                            //Origine en bas a gauche
-                            //Rho horizontal vers la droite de 0 a imageDiag
-                            //Theta vertical vers le haut de -90 a 180
-                            int jDisplayRho = round(rho / rhoStep);
-                            int iDisplayTheta = round((180-te) / angleStep);
-
-                            resImg->pixelAt(jDisplayRho, iDisplayTheta, c)++;
+                            //Origine au centre
+                            //Rho vertical vers la droite de -imageDiag a imageDiag
+                            //Theta horizontale vers le haut de -90 à 90
+                            double theta = te;
+                            if(te > 90){
+                                theta = theta - 180;
+                                rho = -rho;
+                            }
+                            int jDisplayRho = round( (rho + imageDiag) / rhoStep) ;
+                            int iDisplayTheta = round( (theta + 90) / angleStep);
+                            resImg->pixelAt( iDisplayTheta, jDisplayRho, c)++;
                         }
                     }
                 }
             }
         }
     }
+    return resImg;
+}
 
 
 
-//    //Exemple d'affichage de texte dans la fentre "texte"
-//    char buffer[455];
-//    sprintf( buffer, "Lecture du rsultat :\nLigne du haut : angle=0\nLigne du bas : angle=+180\nColonne de gauche : distance=0\nColonne de droite : distance max (diagonale de l'image)\nPoint de rfrence pour les distances : coin en haut  gauche\nDroite de rfrence pour les angles : axe VERTICAL\nAngles positifs dans le sens trigonomtrique indirect");
-//    oh->AddString( buffer );
-
-
-
-    return resImg;
-}
 string Transforms::hough2_inverse(const Image_t<double> *image, Image** resImgptr, unsigned int width, unsigned int height, unsigned int threshold) {
 //string Transforms::hough2_inverse(const Image_t<double> *image, Image** resImgptr, unsigned int size, unsigned int threshold) {
 
@@ -189,10 +181,10 @@ string Transforms::hough2_inverse(const Image_t<double> *image, Image** resImgpt
 //    sprintf( buffer, "Valeur Max de la matrice d'entre=%d",(int)(max+0.1));
 
 
-    double angleStep = 270. / image->getHeight(); //les angles varient de -90 à +180 = intervalle de longueur 270 degre
+    double angleStep = 180. / (image->getWidth() - 1) ; 
     double imageDiag = sqrt(width*width + height*height);
-    double rhoStep = imageDiag / (image->getWidth() - 1 );
-
+    double rhoStep = imageDiag / ( (image->getHeight() - 1 ) /2 );
+    
     //Algorithme de traitement
 
     int cmpt = 0;
@@ -204,32 +196,27 @@ string Transforms::hough2_inverse(const Image_t<double> *image, Image** resImgpt
                 if(n >= threshold)
                 {
                     cmpt++;
-                    double angle = (180 - (angleStep * i)) / 180. * pi;
-                    double rho = rhoStep * j;
+                    double angle = pi * (j * angleStep - 90) / 180 ; 
+                    double rho = rhoStep * i - imageDiag;
                     double sinte = sin(angle);
                     double coste = cos(angle);
 
-    //                sprintf( tampon,"\nniveau=%d\tangle=%1.0f\tdistance=%1.0f",(int)(0.1+tab_image[i+nl*j]),angle/pi*180.,rho);
-    //                strcat( buffer, tampon);
-
                     //Construction de la droite d'quation rho = x*coste + y*sinte
-                    for(unsigned int jj = 0; jj < width; ++jj) {
+                    for(unsigned int jj = 0; jj < height; ++jj) {
                         double x = jj;
                         double y = (rho - x*coste)/sinte;
-                        int ii = height-round(y);
-//                        int kk = rho * (cos(angle) + tan(angle) * sin(angle)) - tan(angle)*jj;
-                        if( ii >= 0 && ii < height) {
-                            resImg->pixelAt(jj, ii, c) += n;
+                        int ii = round(y);
+                        if( ii >= 0 && ii < width) {
+                            resImg->pixelAt(ii, jj, c) += n;
                         }
 
                     }
-                    for(unsigned int ii = 0; ii < height; ++ii) {
-    //                    int kk = ( rho * (cos(angle) + tan(angle) * sin(angle)) -ii ) / tan(angle);
-                        double y = height - ii;
+                    for(unsigned int ii = 0; ii < width; ++ii) {
+                        double y = ii;
                         double x = (rho-y*sinte)/coste;
                         int jj = round(x);
-                        if( jj>=0 && jj < width) {
-                            resImg->pixelAt(jj, ii, c) += n;
+                        if( jj>=0 && jj < height) {
+                            resImg->pixelAt(ii, jj, c) += n;
                         }
                      }
                 }
@@ -247,8 +234,7 @@ string Transforms::hough2_inverse(const Image_t<double> *image, Image** resImgpt
     Image::iterator jt = resStdImg->begin();
     double max = resImg->max();
     while(it != resImg->end()) {
-        // tester avec 255 et sans le +0.5
-        *jt = *it * 256. / max + 0.5;
+        *jt = *it * 255. / max + 0.5;
         ++it;
         ++jt;
     }
-- 
GitLab