summaryrefslogtreecommitdiff
path: root/2005/i/robert/src/ovision/see/skittle.cc
blob: a1b4bfd85f07c09ddd286f36b55294bd6f54c4ab (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
// 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)
{
    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 = 30;
    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/5;
    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
    for (std::vector<Hpoint>::iterator iter = l.begin (); iter != l.end (); ++iter)
	std::cout << (*iter)[0] << " " << (*iter)[1] << std::endl;
    Hotelling hote (l);
    hote.eigenVectors ();
    double i, j;
    hote.getPC (i, j);
    hote.show ();
    std::cout << "PC : " << i << "  " << j << std::endl;
}

/// 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) 
      {
//	std::cout << startX << " " << startY << std::endl;
	--startY;
      }
    return startY;
}

/// Recherche de du c�t� de la courbure
Skittle::BendType
Skittle::bend (Zone &zone)
{
    /// Border
    const int border = 20;
    /// Initialisation du saut de point
    int jump = oconfig_->jumpPointDist/5;
    if (!jump) jump = 1;
    /// Initialisation du point de d�part
    const int startY = (int)(zone.ymin + (zone.ymax - zone.ymin) * 0.25);
    /// 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 << firstPoint << " " << lastPoint << " " << limitPoint << std::endl;
    int above = 0; int below = 0;
    /// 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 * 0.90) - 2;

    BendType bending = error;
    if (above > score) bending = up;
    else if (below > score) bending = down;
    
    std::cout << "courb " << bending << std::endl; 
    return bending;
}

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