summaryrefslogtreecommitdiff
path: root/2005/i/robert/src/ovision/see/skittle.cc
blob: 3fb5f645ff62cbf156d31645bb4773d32b7e0999 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// skittle.cc - Classe Skittle
// robert - Programme du robot APBteam
// Copyright (C) 2005 Olivier Gaillard

/// @file skittle.cc  Reconnaissance des objets quilles

#include <iostream>

#include "skittle.hh"
#include "hotelling.hh"
    
/// Constructeur
Skittle::Skittle (Img *img, Segm *segm)
    : segm_ (segm), img_ (img), pcX_ (0), pcY_ (0)
{
    oconfig_ = OConfig::getInstance (); 
}

/// Destructeur
Skittle::~Skittle (void)
{
}

/// Recherche de la composante principale 
void
Skittle::pca (Zone &zone)
{
    // Agrandissement de la zone de recherche
    const int grow = oconfig_->skittleGrow;
    int ymin = minWithBorder (zone.ymin - grow, 0);
    int ymax = maxWithBorder (zone.ymax + grow, img_->height_);
    int xmin = minWithBorder (zone.xmin - grow, 0);
    int xmax = maxWithBorder (zone.xmax + grow, img_->width_);
    /// Initialisation du saut de point
    int jump = oconfig_->jumpPointDist/oconfig_->skittleDivJump;
    if (!jump) jump = 1;
    // Parcours d'une partie des pixels de l'image
    int tmpY;
    std::vector<Hpoint> l;
    for (int y = ymin; y < ymax; y += jump) 
      {
	tmpY = y*img_->width_;
	for (int x = xmin; x < xmax; x += jump) 
	    if (segm_->giveColor (img_->tabData_ + ((tmpY + x) * 3), true, true) == zone.color)
	      {
		Hpoint h (x, y);
		l.push_back (h);
	      }
      }
    // Calcul de la composante principale
    Hotelling hote (l);
    hote.eigenVectors ();
    hote.getPC (pcX_, pcY_);
}

/// Utilis� pour la recherche de la courbure, cherche le point le plus haut
int
Skittle::climb (const int startX, int startY, const int color)
{
    while (segm_->giveColor (img_->tabData_ + ((startY*img_->width_ + startX) * 3), true, true) == color) 
	--startY;
    return startY;
}

/// V�rifie qu'un catadiopre est � proximit�
int
Skittle::isReflectBand (Zone &zone, std::vector<Zone> &listReflectBand)
{
    // Test les variables de composantes principales
    if (!pcX_ && !pcY_ && listReflectBand.size ())
      {
	// Parcours la liste des catadiopres
	for (std::vector<Zone>::iterator iter = listReflectBand.begin ();
	     iter != listReflectBand.end (); ++iter)
	  {
	    // Test la distance cart�sienne
	    if (dist (iter->centerx, iter->centery, zone.centerx, zone.centery))
		// Test la distance orthogonale
		if (orthoDist (iter->centerx - zone.centerx, iter->centery - zone.centery,
			       pcX_, pcY_))
		    return 1;
		    	    
	  }
      }
      return 0;
}

/// Recherche de du c�t� de la courbure
Skittle::BendType
Skittle::bend (Zone &zone)
{
    /// Border
    const int border = oconfig_->skittleBorder;
    /// Initialisation du saut de point
    int jump = oconfig_->jumpPointDist/oconfig_->skittleDivJump;
    if (!jump) jump = 1;
    /// Initialisation du point de d�part
    const int startY = minWithBorder ((int)(zone.ymin + (zone.ymax - zone.ymin) * 0.25), 0);
    /// Point sup�rieur de la quille
    int upperPoint;
    /// Recherche du premier et du dernier point
    int firstPoint = climb (maxWithBorder (zone.xmin + border, img_->width_), startY, zone.color);
    int lastPoint = climb (minWithBorder (zone.xmax - border, 0), startY, zone.color);
    int limitPoint = firstPoint > lastPoint ? firstPoint : lastPoint; 
    std::cout << "<Skittle::bend> " << firstPoint << " " << lastPoint << " " << limitPoint << std::endl;
    int above = 0; int below = 0;
    std::cout << "<Skittle::bend> ";
    /// Parcours des autres points
    for (int i = zone.xmin + border + jump; i < zone.xmax - border - jump; i+=jump)
      {
	upperPoint = climb (i, startY, zone.color);
	std::cout << upperPoint << " ";
	if (upperPoint > limitPoint) ++below;
	else ++above;
      }
    std::cout << std::endl;
    const int score = (int)((zone.xmax - zone.xmin - 2*border) / jump * oconfig_->skittleScoreBendRatio) - 2;

    BendType bending = error;
    if (above > score) bending = up;
    else if (below > score) bending = down;
    
    return bending;
}

/// Analyse la zone
bool
Skittle::analyse (Zone &zone, std::vector<Zone> &listReflectBand)
{
    // group est partiel ? 
    // if (zone.partial)
    // quille verticale sur l'image ?
    if ((zone.ymax - zone.ymin)/(double)(zone.xmax - zone.xmin) > oconfig_->skittleVerticalRatio)
      {
	std::cout << "vertical !!!" << std::endl;
	// debout ou couch� ?
	bend_ = bend (zone);
	isReflectBand (zone, listReflectBand);
      }
    else
	// calcul de l'orientation
	pca (zone);
    return true;
}

/// Affiche les infos sur la quille
void 
Skittle::show () const
{
    std::cout << "<Skittle::show> position : " << (bend_ == up ? "up"
					       : (bend_ == down ? "down" : "error")) << "\n";
    std::cout << "<Skittle::show> orientation : " << pcX_ << ", " << pcY_ << std::endl;
}