| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
- /*******************************************************************\
- Fichier : Stenose.cpp
- Date : 20/04/98
- Version : 1.001
- Description : fonctions de mesures de sténose
- |*******************************************************************|
- Bugs:
- Notes:
- L'ellipse donnée peut être entièrement contenue dans le vaisseau,
- c'est pour cela que l'on utilise les régions plutôt que le
- rectangle englobant qui peut contenir des points de couleur.
- Un rapport entre la surface de l'ellipse et du rectangle est
- donc erroné, si des points de couleur sont entre le rectangle
- et l'ellipse
- |*******************************************************************|
- Historique :
- 20/04/98 1.001 : L'ellipse n'était pas affichée si aucun point n'était
- détecté
- 24/07/97 1.000 : Première version
- \*******************************************************************/
- #include <limits>
- #include "StenoseBase.h"
- #include "Ressource.h"
- //#include "../IMT/MeanEstimate.h"
- #include "CStenoseResult.h"
- #include "StenoseResult.h"
- #include "../Object/regionEllipse.h"
- #include "../Object/point.h"
- #include "../NR/ToolsMath.h"
- #include "../Container/extendedimage.h"
-
- CStenoseBase::CStenoseBase (void)
- {
- m_pPoints = NULL;
- Release ();
- }
- CStenoseBase::~CStenoseBase()
- {
- Release ();
- }
- double CStenoseBase::SurfaceEllipse ()
- {
- return m_dblEllipse;
- }
- double CStenoseBase::SurfaceStenose ()
- {
- return m_dblStenose;
- }
- double CStenoseBase::Ratio ()
- {
- return m_dblRatio;
- }
- bool CStenoseBase::Measure(ExtendedImage *h_image, Rect &rcEllipse)
- {
- m_image = h_image;
- assert(g_pCurrentScale);
- long dwEllipse,
- dwX,
- dwY,
- dwEnd,
- dwColor;
- RegionEllipse rgnEllipse;
- bool fColor;
- // on libère les ressources allouées pour la précédente mesure
- Release();
- // définition de la zone de mesure
- m_rcDraw = rcEllipse;
- m_rcDraw.right++;
- m_rcDraw.bottom++;
-
- rgnEllipse.CreateEllipticRgn(m_rcDraw);
- dwColor = 0; // nombre de points de couleur dans l'ellipse
- dwEllipse = 0; // nombre de points dans l'ellipse
- // nombre maximal de points qui pourraient être affichés
- m_pPoints = new Point [rcEllipse.Width() * rcEllipse.Height() / 2];
- // Balayage horizontal!
- for (dwY = rcEllipse.top; ((long) dwY) < rcEllipse.bottom; dwY++)
- {
- // afin d'accélérer les mesures, on ne travaille que sur les points du segment de droite
- // horizontale à l'interieur de l'ellipse
- // Point d'abscisse maximal
- dwEnd = rcEllipse.right;
- while ((!rgnEllipse.PtInRegion0(dwEnd, dwY)) && ((int) dwEnd >= rcEllipse.left)) // un des points appartient nécessairement à l'ellipse
- dwEnd--;
- // Point d'abscisse minimal
- dwX = rcEllipse.left + rcEllipse.right - dwEnd;
- // Premier point de couleur ou non?
- fColor = IsColor(dwX, dwY);
- if (fColor)
- {
- m_pPoints [m_dwPoints].x = dwX;
- m_pPoints [m_dwPoints].y = dwY;
- m_dwPoints++; // a été réinitialisé par Release
- }
- // On parcours le segment de droite...
- while (dwX <= dwEnd)
- {
- dwEllipse++; // Nombre de point intérieur à l'ellipse incrémenté!
- assert (PointInBuffer (dwX, dwY));
-
- if (IsColor(dwX, dwY))
- {
- dwColor++;
- if (!fColor)
- {
- // On passe d'une zone NB à une zone RGB
- fColor = true;
- m_pPoints [m_dwPoints].x = dwX;
- m_pPoints [m_dwPoints].y = dwY;
- m_dwPoints++;
- }
- }
- else if (fColor)
- {
- // On passe d'une zone RGB à une zone NB
- fColor = false;
- m_pPoints[m_dwPoints].x = dwX;
- m_pPoints[m_dwPoints].y = dwY;
- m_dwPoints++;
- }
- dwX++;
- }
- }
- // Fin du balayage horizontal!
- // Balayage vertical!
- for (dwX = rcEllipse.left; ((long) dwX) < rcEllipse.right; dwX++)
- {
- // afin d'accélérer les mesures, on ne travaille que sur les points du segment de droite
- // verticale à l'interieur de l'ellipse
- // Point d'ordonnée maximal
- dwEnd = rcEllipse.bottom;
- while ((!rgnEllipse.PtInRegion0(dwX, dwEnd)) && ((int) dwEnd >= rcEllipse.top)) // un des points appartient nécessairement à l'ellipse
- dwEnd--;
- // Point d'ordonnée minimal
- dwY = rcEllipse.top + rcEllipse.bottom - dwEnd;
- // Premier point de couleur ou non?
- fColor = IsColor(dwX, dwY);
- if (fColor)
- {
- m_pPoints[m_dwPoints].x = dwX;
- m_pPoints[m_dwPoints].y = dwY;
- m_dwPoints++; // a été réinitialisé par Release
- }
- // On parcours le segment de droite...
- while (dwY <= dwEnd)
- {
- assert(PointInBuffer(dwX, dwY));
- if (IsColor(dwX, dwY))
- {
- if (!fColor)
- {
- // On passe d'une zone NB à une zone RGB
- fColor = true;
- m_pPoints[m_dwPoints].x = dwX;
- m_pPoints[m_dwPoints].y = dwY;
- m_dwPoints++;
- }
- }
- else if (fColor)
- {
- // On passe d'une zone RGB à une zone NB
- fColor = false;
- m_pPoints[m_dwPoints].x = dwX;
- m_pPoints[m_dwPoints].y = dwY;
- m_dwPoints++;
- }
- dwY++;
- }
- }
- // Fin du balayage vertical!
- m_dblRatio = 100 * (1. - double (dwColor) / dwEllipse);
- m_dblEllipse = g_pCurrentScale->Surface (rcEllipse.Width(), rcEllipse.Height()) * M_PI / 4;
-
- m_dblStenose = m_dblEllipse * m_dblRatio / 100.0;
-
- m_rcDraw = rcEllipse;
- m_rcDraw.bottom--;
- m_rcDraw.right--;
- return(true); // on retourne toujours un résultat
- } // fin de Measure
- void CStenoseBase::Release()
- {
- m_rcDraw.SetRectEmpty ();
- if (m_pPoints)
- {
- delete [] m_pPoints;
- m_pPoints = NULL;
- }
- m_dwPoints = 0; // requis par la routine de mesure
- }
- bool CStenoseBase::PointInBuffer(const int& x, const int& y)
- {
- Point pt;
- pt.x = x;
- pt.y = y;
- return PointInBuffer(pt);
- }
- bool CStenoseBase::PointInBuffer(const Point& pt)
- {
- assert( m_image );
- int dx = m_image->GetWidth();
- int dy = m_image->GetHeight();
- return ( pt.x >= 0 && pt.y >= 0 && pt.x < dx && pt.y < dy );
- }
- /*
- unsigned long CStenoseBase::GetPixel(const int& x, const int& y)
- {
- Point pt;
- pt.x = x;
- pt.y = y;
- return GetPixel(pt);
- }
- unsigned long CStenoseBase::GetPixel(const Point& pt)
- {
- assert( m_image );
- //#if defined( WIN32 ) && !defined( IMT_DLL )
- // return m_image->GetPixel( pt.x, pt.y );
- //#else
- return *m_image->GetPixel( pt.x, pt.y );
- //#endif
- }
- */
- bool CStenoseBase::IsColor(int x, int y)
- {
- unsigned char bRed;
- unsigned char bGreen;
- unsigned char bBlue;
- int iRed;
- int iGreen;
- int iBlue;
- // AffectLeadResult();
- bRed = m_image->GetPixelRGB( x, y, 0);
- bGreen = m_image->GetPixelRGB( x, y, 1);
- bBlue = m_image->GetPixelRGB( x, y, 2);
- iRed = (int) bRed;
- iGreen = (int) bGreen;
- iBlue = (int) bBlue;
- // un niveau de gris implique bRed = bGreen = bBlue
- // étant donné que l'image a été numérisé on autorise un delta de 10 entre chaque couleur
- // ex : 190 197 185 est gris, 190 201 190 est en couleur
- return ( (abs (iRed - iGreen) > 30)
- || (abs (iRed - iBlue ) > 30)
- || (abs (iGreen - iBlue ) > 30)
- );
- }
- void CStenoseBase::PutPixEllipse(float xc,float yc,float x,float y)
- {
- WritePixel( (int) (xc + x), (int) (yc + y));
- WritePixel( (int) (xc - x), (int) (yc - y));
- WritePixel( (int) (xc + x), (int) (yc - y));
- WritePixel( (int) (xc - x), (int) (yc + y));
- }
- void CStenoseBase::WritePixel(int x, int y)
- {
- x = 0;
- y = 0;
- }
- // Algorithme MidPoint de dessin d'une Ellipse
- void CStenoseBase::myDrawEllipse()
- {
- float x = 0, y = 0;
- double p1, p2, t1, t2;
- int k;
- float rx, ry, xc, yc;
- rx = (float) (m_rcDraw.right - m_rcDraw.left) / 2;
- ry = (float) (m_rcDraw.bottom - m_rcDraw.top) / 2;
- xc = m_rcDraw.left + rx;
- yc = m_rcDraw.top + ry;
- y = ry;
- p1 = ry * ry - rx * rx * ry + 0.25 * rx * rx;
-
- PutPixEllipse(xc, yc, x, y);
- for (k = 0; (2 * ry * ry * x) <= (2 * rx * rx * y); k++)
- {
- t1 = 2 * ry * ry * x + 2 * ry * ry;
- t2 = 2 * rx * rx * y - 2 * rx * rx;
-
- if (p1 < 0)
- {
- p1 = p1 + t1 + ry * ry;
- }
- else
- {
- p1 = p1 + t1 - t2 + ry * ry;
- y--;
- }
- x++;
- PutPixEllipse(xc, yc, x, y);
- }
- p2 = ry * ry * ( x + 0.5 ) * ( x + 0.5 ) + rx * rx * (y - 1) * (y - 1) - rx * rx * ry * ry;
-
- PutPixEllipse(xc, yc, x, y);
- for (k = 0 ; y >= 0 ; k++)
- {
- t1 = 2 * ry * ry * x + 2 * ry * ry;
- t2 = 2 * rx * rx * y - 2 * rx * rx;
-
- if (p2 > 0)
- {
- p2 = p2 - t2 + rx * rx;
- }
- else
- {
- p2 = p2 + t1 - t2 + rx * rx;
- x++;
- }
- y--;
- PutPixEllipse(xc, yc, x, y);
- }
- }
|