summaryrefslogtreecommitdiff
path: root/2005/i/robert/src/ovision/see/skittle.cc
blob: 45462c1bb9d8ee5e2479aa4689f7ae029c63ba54 (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
// 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 = (zone.ymin - grow);
    ymin = (ymin > 0) ? ymin : 0;
    int ymax = (zone.ymax + grow);
    ymax = (ymax < img_->height_) ? ymax : img_->height_;
    int xmin = (zone.xmin - grow);
    xmin = (xmin > 0) ? xmin : 0;
    int xmax = (zone.xmax + grow);
    xmax = (xmax < img_->width_) ? xmax : 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 = zone.ymin - grow; y < zone.ymax + grow; y += jump) 
      {
	tmpY = y*img_->width_;
	for (int x=zone.xmin - grow; x < zone.xmax + grow; 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 (zone.xmin + border, startY, zone.color);
    int lastPoint = climb (zone.xmax - border, 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;
}