Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / colonet / server / vision / vision.c @ 534

History | View | Annotate | Download (4.32 KB)

1
/**
2
 * Robot Detection
3
 * based on opencv's sample program fitellipse.c by Denis Burenkov
4
 *
5
 * @author Rich Hong
6
 * @date 11/18/2007
7
 */
8

    
9
#include <vision.h>
10

    
11
#include <cv.h>
12
#include <highgui.h>
13

    
14
#include <stdio.h>
15
#include <stdlib.h>
16

    
17
#define MINH 100 //min threshold level
18
#define MAXH 160 //max threshold level
19

    
20
#define DEBUG 0 //Debug to find threshold level
21

    
22
struct CenterP {
23
  CvPoint center;
24
  int count;
25
};
26

    
27
static char* filename;
28

    
29
int vision_init(char* filename_) {
30
  filename = filename_;
31
  return 0;
32
}
33

    
34
int vision_get_robot_positions(VisionPosition** positions) {
35
  IplImage* image03;
36

    
37
  // load image and force it to be grayscale
38
  if ((image03 = cvLoadImage(filename, 0)) == 0) {
39
    fprintf(stderr, "Failed to load image.\n");
40
    return -1;
41
  }
42

    
43
  // Create the destination images
44
  IplImage* image02 = cvCloneImage(image03);
45
  IplImage* image04 = cvCloneImage(image03);
46

    
47
  if (DEBUG) cvNamedWindow("Result", 1);
48

    
49
  // Create dynamic structure and sequence.
50
  CvMemStorage* stor = cvCreateMemStorage(0);
51
  CvSeq* cont = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint) , stor);
52

    
53
  struct CenterP bestc[100];
54
  int index=0;
55

    
56
  for (int h = MINH; h < MAXH; h++) {
57
    // Threshold the source image. This needful for cvFindContours().
58
    cvThreshold(image03, image02, h, 255, CV_THRESH_BINARY);
59

    
60
    // Find all contours.
61
    cvFindContours(image02, stor, &cont, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_NONE, cvPoint(0,0));
62

    
63
    // Clear images. IPL use.
64
    cvZero(image02);
65
    cvZero(image04);
66

    
67
    // This cycle draw all contours and approximate it by ellipses.
68
    for(; cont; cont = cont->h_next) {
69
      int i; // Indicator of cycle.
70
      int count = cont->total; // This is number point in contour
71
      CvPoint center;
72
      CvSize size;
73

    
74
      // Number point must be more than or equal to 6 (for cvFitEllipse_32f).
75
      if (count < 6) continue;
76

    
77
      // Alloc memory for contour point set.
78
      CvPoint* PointArray = (CvPoint*) malloc(count * sizeof(CvPoint));
79
      CvPoint2D32f* PointArray2D32f= (CvPoint2D32f*) malloc(count * sizeof(CvPoint2D32f));
80

    
81
      // Alloc memory for ellipse data.
82
      CvBox2D32f* box = (CvBox2D32f*)malloc(sizeof(CvBox2D32f));
83

    
84
      // Get contour point set.
85
      cvCvtSeqToArray(cont, PointArray, CV_WHOLE_SEQ);
86

    
87
      // Convert CvPoint set to CvBox2D32f set.
88
      for(i=0; i<count; i++) {
89
        PointArray2D32f[i].x = (float)PointArray[i].x;
90
        PointArray2D32f[i].y = (float)PointArray[i].y;
91
      }
92

    
93
      // Fits ellipse to current contour.
94
      cvFitEllipse(PointArray2D32f, count, box);
95

    
96
      // Convert ellipse data from float to integer representation.
97
      center.x = cvRound(box->center.x);
98
      center.y = cvRound(box->center.y);
99
      size.width = cvRound(box->size.width*0.5);
100
      size.height = cvRound(box->size.height*0.5);
101
      box->angle = -box->angle;
102

    
103
      if (size.width>10&&size.height>10&&size.width<20&&size.height<20){
104
        //printf("%d %d %d %d\n",center.x,center.y,size.width,size.height);
105

    
106
        int found=0, j;
107
        for (j = 0; j < index; j++) {
108
          if (abs(bestc[j].center.x-center.x)<9&&abs(bestc[j].center.y-center.y)<9) {
109
            bestc[j].count++;
110
            found=1;
111
            break;
112
          }
113
        }
114

    
115
        if (!found){
116
          struct CenterP c;
117
          c.center=center;
118
          c.count=1;
119
          bestc[index]=c;
120
          index++;
121
        }
122
      }
123

    
124
      // Free memory.
125
      free(PointArray);
126
      free(PointArray2D32f);
127
      free(box);
128
    }
129
  }
130

    
131
  image04 = cvCloneImage(image03);
132

    
133
  int count = 0;
134
  int i;
135
  for (i = 0; i < index; i++) {
136
    if (bestc[i].count > 7){
137
      count++;
138
    }
139
  }
140

    
141
  VisionPosition* pos_array = (VisionPosition*)malloc(sizeof(VisionPosition) * count);
142
  if (pos_array == NULL) {
143
    fprintf(stderr, "malloc failed\n");
144
    return -1;
145
  }
146

    
147
  int c = 0;
148
  for (i = 0; i < index; i++) {
149
    if (bestc[i].count > 7){
150
      pos_array[c].x = bestc[i].center.x;
151
      pos_array[c].y = bestc[i].center.y;
152
      c++;
153

    
154
      if (DEBUG) cvCircle(image04, bestc[i].center, 20, CV_RGB(0,0,0), 5, 8, 0);
155
    }
156
  }
157

    
158
  if (DEBUG) cvWaitKey(0);
159

    
160
  cvReleaseImage(&image02);
161
  cvReleaseImage(&image03);
162

    
163
  if (DEBUG) cvDestroyWindow("Result");
164

    
165
  // Show image. HighGUI use.
166
  if (DEBUG) cvShowImage( "Result", image04 );
167

    
168
  cvReleaseImage(&image04);
169

    
170
  cvReleaseMemStorage(&stor);
171

    
172
  *positions = pos_array;
173
  return count;
174
}