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