123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- /*********************************************************************/
- /* */
- /* Copyright 2022-2023 Rémi Synave - remi.synave@univ-littoral.fr */
- /* */
- /* This file is part of DSL. */
- /* This software uses Qt to build the Graphical User Interface */
- /* https://www.qt.io/ */
- /* */
- /* DSL is free software: you can redistribute it and/or modify */
- /* it under the terms of the GNU General Public License as published */
- /* by the Free Software Foundation, either version 3 of the License, */
- /* or (at your option) any later version. */
- /* */
- /* DSL is distributed in the hope that it will be useful, */
- /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
- /* GNU General Public License for more details. */
- /* */
- /* You should have received a copy of the GNU General Public License */
- /* along with DSL. If not, see <http://www.gnu.org/licenses/>. */
- /* */
- /*********************************************************************/
- #include <cstdlib>
- #include <ctime>
- #include <stdexcept>
- #include <QDebug>
- #include "StrengthLine.hpp"
- StrengthLine::StrengthLine (double ax, double ay, double bx, double by)
- {
- if (p1 == NULL || p2 == NULL)
- throw std::
- invalid_argument ("Points defining a strength line can't be NULL.");
- if (ax == bx && ay == by)
- throw std::
- invalid_argument ("Points defining a strength line can't be equals.");
- this->p1 = new QPoint(ax, ay);
- this->p2 = new QPoint(bx, by);
- }
- StrengthLine::StrengthLine (QPoint * p1, QPoint * p2)
- {
- if (p1 == NULL || p2 == NULL)
- throw std::
- invalid_argument ("Points defining a strength line can't be NULL.");
- if (p1->x () == p2->x () && p1->y () == p2->y ())
- throw std::
- invalid_argument ("Points defining a strength line can't be equals.");
- this->p1 = p1;
- this->p2 = p2;
- }
- QPoint*
- StrengthLine::getP1() const
- {
- return new QPoint(*p1);
- }
- QPoint*
- StrengthLine::getP2() const
- {
- return new QPoint(*p2);
- }
- std::pair < float, float >
- StrengthLine::equation () const
- {
- // This method can be called only if a and b are
- // not aligned into a vertical or horizontal line
- float a = ((p1->y () - p2->y ()) * 1.0) / (p1->x () - p2->x ());
- float b = p1->y () - a * p1->x ();
- return std::make_pair (a, b);
- }
- std::pair < QPoint *, QPoint * >StrengthLine::toDraw (QImage * img) const
- {
- return this->toDraw(img->width(), img->height());
- }
- std::pair < QPoint *, QPoint * >StrengthLine::toDraw (int imgWidth, int imgHeight) const
- {
- // Methode qui va calculer les points pour l'affichage des droites
- // sur l'image passées en paramètre. Calcul rapide donc
- // les points peuvent sortir de l'image.
- // ligne verticale
- if (p1->x () == p2->x ())
- return std::make_pair (new QPoint (p1->x (), 0),
- new QPoint (p1->x (), imgHeight));
- // ligne horizontale
- if (p1->y () == p2->y ())
- return std::make_pair (new QPoint (0, p1->y ()),
- new QPoint (imgWidth, p1->y ()));
- // Equation de la droite et on prend les points gauche et droite de la ligne
-
- std::pair < float, float >
- eq = this->equation ();
- float
- a = std::get < 0 > (eq);
- float
- b = std::get < 1 > (eq);
- return std::make_pair (new QPoint (0, b),
- new QPoint (imgWidth, imgWidth * a + b));
- }
- std::pair < QPoint *, QPoint * >StrengthLine::interpolateToEdge (QImage * img) const
- {
- return this->interpolateToEdge(img->width(), img->height());
- }
- std::pair < QPoint *, QPoint * >StrengthLine::interpolateToEdge (int imgWidth, int imgHeight) const
- {
- // Methode qui va calculer les points sur les bords des images
- // en fonction des deux points attributs qui définissent
- // la ligne.
- // ligne verticale
- if (p1->x () == p2->x ())
- return std::make_pair (new QPoint (p1->x (), 0),
- new QPoint (p1->x (), imgHeight));
- // ligne horizontale
- if (p1->y () == p2->y ())
- return std::make_pair (new QPoint (0, p1->y ()),
- new QPoint (imgWidth, p1->y ()));
- // Equation de la droite et on prend les points gauche et droite de la ligne
- std::pair < float, float >
- eq = this->equation ();
- float
- a = std::get < 0 > (eq);
- float
- b = std::get < 1 > (eq);
- QPoint *p1 = new QPoint(0, b);
- QPoint *p2 = new QPoint(imgWidth, imgWidth * a + b);
- // Si le point de gauche est trop bas
- if(b < 0)
- {
- p1->setX(-b/a);
- p1->setY(0);
- }
- // Si le point de gauche est trop haut
- if(b > imgHeight)
- {
- p1->setX((imgHeight-b)/a);
- p1->setY(imgHeight);
- }
- // Si le point de droite est trop bas
- if((imgWidth * a + b) < 0)
- {
- p2->setX(-b/a);
- p2->setY(0);
- }
- // Si le point de droite est trop haut
- if((imgWidth * a + b) > imgHeight)
- {
- p2->setX((imgHeight-b)/a);
- p2->setY(imgHeight);
- }
-
- return std::make_pair (p1, p2);
- }
- float StrengthLine::ea_score(const StrengthLine *sl, double imgWidth, double imgHeight) const
- {
- std::pair < QPoint*, QPoint* > pointsSL1 = this->interpolateToEdge (imgWidth, imgHeight);
- std::pair < QPoint*, QPoint* > pointsSL2 = sl->interpolateToEdge (imgWidth, imgHeight);
- QPoint* p1SL1 = std::get < 0 > (pointsSL1);
- QPoint* p2SL1 = std::get < 1 > (pointsSL1);
- QPoint* p1SL2 = std::get < 0 > (pointsSL2);
- QPoint* p2SL2 = std::get < 1 > (pointsSL2);
- float u[2] = {p2SL1->x()-p1SL1->x(), p2SL1->y()-p1SL1->y()};
- float v[2] = {p2SL2->x()-p1SL2->x(), p2SL2->y()-p1SL2->y()};
- float normU = sqrt(u[0]*u[0]+u[1]*u[1]);
- float normV = sqrt(v[0]*v[0]+v[1]*v[1]);
- u[0]=u[0]/normU;
- u[1]=u[1]/normU;
- v[0]=v[0]/normV;
- v[1]=v[1]/normV;
- float angle = 0;
-
- if((u[0]!=v[0]) || (u[1]!=v[1]))
- {
- float prodScal=u[0]*v[0]+u[1]*v[1];
-
- // In case of number approximation...
- if(prodScal>1)
- prodScal=1;
- if(prodScal<-1)
- prodScal=-1;
-
- angle = acos(prodScal);
- }
- float sT = 1 - (angle/(M_PI/2));
- float midSL1X = ((p1SL1->x() + p2SL1->x())/2.0)/(imgWidth*1.0);
- float midSL1Y = ((p1SL1->y() + p2SL1->y())/2.0)/(imgHeight*1.0);
- float midSL2X = ((p1SL2->x() + p2SL2->x())/2.0)/(imgWidth*1.0);
- float midSL2Y = ((p1SL2->y() + p2SL2->y())/2.0)/(imgHeight*1.0);
- float sd = 1 - sqrt(((midSL1X-midSL2X)*(midSL1X-midSL2X))+((midSL1Y-midSL2Y)*(midSL1Y-midSL2Y)));
- return ((sT*sd)*(sT*sd));
- }
- StrengthLine* StrengthLine::getRandomLine (QImage * img)
- {
- std::srand(static_cast<unsigned int>(std::time(nullptr)+std::rand()));
-
- int x1rand = std::rand() % img->width();
- int x2rand = std::rand() % img->width();
- int y1rand = std::rand() % img->height();
- int y2rand = std::rand() % img->height();
- while ( x1rand == x2rand && y1rand==y2rand )
- {
- x2rand = std::rand() % img->width();
- y2rand = std::rand() % img->height();
- }
- return new StrengthLine( new QPoint(x1rand, y1rand), new QPoint(x2rand, y2rand) );
- }
- StrengthLine* StrengthLine::getRandomLine (int width, int height)
- {
- std::srand(static_cast<unsigned int>(std::time(nullptr)+std::rand()));
-
- int x1rand = std::rand() % width;
- int x2rand = std::rand() % width;
- int y1rand = std::rand() % height;
- int y2rand = std::rand() % height;
- while ( x1rand == x2rand && y1rand==y2rand )
- {
- x2rand = std::rand() % width;
- y2rand = std::rand() % height;
- }
- return new StrengthLine( new QPoint(x1rand, y1rand), new QPoint(x2rand, y2rand) );
- }
|