Project

General

Profile

Statistics
| Revision:

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

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 220 //max threshold level
19
#define DEBUG 0 //Debug to find threshold level
20

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

    
26
static char* filename;
27

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
130
  image04 = cvCloneImage(image03);
131

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

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

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

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

    
157
  if (DEBUG) cvWaitKey(0);
158

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

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

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

    
167
  cvReleaseImage(&image04);
168

    
169
  cvReleaseMemStorage(&stor);
170

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