Project

General

Profile

Statistics
| Branch: | Revision:

root / vision / src / v2v3_converter.cpp @ f3966b0d

History | View | Annotate | Download (5.7 KB)

1
#include <ros/ros.h>
2
#include <stdio.h>
3
#include <vision/TargetDescriptor.h>
4
#include <image_transport/image_transport.h>
5
#include <geometry_msgs/Point.h>
6
#include <tf/transform_listener.h>
7

    
8
ros::Publisher pub;
9
ros::Publisher img_pub;
10

    
11
int hk = 15; 
12
int sk = 255;
13
int vk = 255;
14

    
15
bool isRight(sensor_msgs::Image * img, int p){
16
        return (img->data[p + 1] == img->data[p]);
17
}
18

    
19
bool isLeft(sensor_msgs::Image * img, int p){
20
        return (img->data[p - 1] == img->data[p]);
21
}
22

    
23
bool isUp(sensor_msgs::Image * img, int p){
24
        return (img->data[p - img->width] == img->data[p]);
25
}
26

    
27
bool isDown(sensor_msgs::Image * img, int p){
28
        return (img->data[p + img->width] == img->data[p]);
29
}
30

    
31
bool hasAnAdjacent(sensor_msgs::Image * image, int j){
32
        int nl = image->height; // number of lines
33
        int nc = image->width; 
34
        int nChannels = image->step / image->width;
35
        int pos = j / nChannels; 
36
        if ((pos % nc) != 0){
37
                if (isLeft(image, pos)) return true;
38
        }
39
        if ((pos / nc) != 0){
40
                if (isUp(image, pos)) return true;
41
        }
42
        if ((pos % nc) != nc - 1){
43
                if (isRight(image, pos)) return true;
44
        }
45
        if ((pos / nc) != nc - 1){
46
                if (isDown(image, pos)) return true;
47
        }
48
        else return false;
49
}
50

    
51
/* Detects the blobs in an image within above defined constraints. Transforms image into 255
52
 * for pixels in the blob, 0 for not in the blob.
53
 */
54
void detectBlobs(sensor_msgs::Image * image, int * comX, int * comY, int * area){
55
        int nl = image->height; // number of lines
56
        int nc = image->step; // number of columns
57
        int nChannels = image->step / image->width; // effective width
58
        
59
        // process image
60
        for (int i = 0; i < nl; i++){
61
                for (int j = 0; j < nc; j+= nChannels){
62
                        if (image->data[i * image->width + j] <= hk + 10 && image->data[j] >= hk - 10){
63
                                image->data[i * image->width + j] = 255;
64
                                image->data[i * image->width + j+1] = 255;
65
                                image->data[i * image->width + j+2] = 255;
66
                        }
67
                        else {
68
                                image->data[i * image->width + j] = 0;
69
                                image->data[i * image->width + j+1] = 0;
70
                                image->data[i * image->width + j+2] = 0;
71
                        }
72
                }
73
        }
74

    
75
        int comXSum = 0;
76
        int comYSum = 0;
77
        int blobPixelCount = 0;
78
        for (int i = 0; i < image->width * image->height; i+=nChannels){
79
                if ( !(image->data[i] == 255 && hasAnAdjacent(image, i)) ){
80
                        image->data[i] = 0;
81
                        image->data[i + 1] = 0;
82
                        image->data[i + 2] = 0;
83
                               continue;
84
                }
85
                blobPixelCount++;
86
                comXSum += image->data[i] / 255;
87
                comYSum += image->data[i] / 255;
88
        }
89
  if (blobPixelCount != 0){
90
        // get average
91
          comXSum /= blobPixelCount;
92
          comYSum /= blobPixelCount;
93
  }
94

    
95
        *area = blobPixelCount;
96
        *comX = comXSum;
97
        *comY = comYSum;
98

    
99
  img_pub.publish(*image);
100
}
101

    
102
void convertToHSV(sensor_msgs::Image * orig){
103

    
104
  int nChannels = orig->step / orig->width; 
105
  printf("Converting to HSV \n");
106

    
107
  // get the max, set it as v
108

    
109
  for (int i = 0; i < orig->height * orig->width; i += nChannels){
110
      int h;
111
      int s;
112
      int v; 
113
      int min;
114

    
115
      // get min, max
116
      if (orig->data[i] >= orig->data[i+1] && orig->data[i] >= orig->data[i+2]){
117
        v = orig->data[i];
118
        if (orig->data[i+1] >= orig->data[i+2]){
119
            min = orig->data[i+2];
120
        }
121
        else min = orig->data[i+1];
122
      }
123
      else if (orig->data[i+1] >= orig->data[i] && orig->data[i+1] >= orig->data[i+2]){
124
        v = orig->data[i+1];
125
        if (orig->data[i] >= orig->data[i+2]){
126
          min = orig->data[i+2];
127
        }
128
        else min = orig->data[i];
129
      }
130
      else {
131
        v = orig->data[i+2];
132
        if (orig->data[i] >= orig->data[i+1]){
133
            min = orig->data[i+1];
134
        }
135
        else min = orig->data[i];
136
      }
137

    
138
      // set s
139
      if (v != 0){
140
      s = (v - min) / v; 
141
      }
142
      else s = 0;
143

    
144
      // set h
145
      if (s == 0) h = 0;
146
      else if (v == orig->data[i]){
147
        h = 60 * (orig->data[i+1] - orig->data[i+2]) / s;
148
      }
149
      else if (v == orig->data[i+1]){
150
        h = 120 + 60 * (orig->data[i+2] - orig->data[i]) / s;
151
      }
152
      else {
153
        h = 240 + 60 * (orig->data[i] - orig->data[i + 1]) / s;
154
      }
155
      
156
      orig->data[i] = h;
157
      orig->data[i+1] = s;
158
      orig->data[i+2] = v;
159

    
160
  }
161
  printf("Conversion complete\n");
162
}
163

    
164
void target_cb(const sensor_msgs::Image orig) {
165

    
166
  printf("beginning callback \n");
167
  tf::TransformListener listener;
168
  geometry_msgs::Point point;
169
  tf::StampedTransform transform;
170
  /*try {
171
    listener.lookupTransform("/camera", "/kinect", ros::Time(0), transform);
172
  }
173
  catch (tf::TransformException ex) {
174
    ROS_ERROR("%s", ex.what());
175
  }*/
176

    
177
  // convert to OpenCV
178

    
179
  sensor_msgs::Image copy = orig;
180
  sensor_msgs::Image * source = &copy; // pointer to the image
181
  sensor_msgs::Image hsvImage = orig; // May be time 
182
  sensor_msgs::Image * hsvPtr = &hsvImage;
183

    
184
  // convert to HSV
185
  
186
  convertToHSV(source);
187

    
188
  // detect blob
189

    
190
  int comX; 
191
  int comY;
192
  int area;
193
  
194
  detectBlobs(hsvPtr, &comX, &comY, &area);
195

    
196
  int distance;
197

    
198
  // give distance as inversely proportional to area, for (x,y,z) 
199
  if (area > 10){
200
    
201
    distance = 100.0 / (float) area;
202

    
203
  }
204
  else {
205
    distance = -1;
206
  } 
207

    
208
  // fill point based on target and tf
209

    
210
  geometry_msgs::Point origPoint;
211

    
212
  // TODO: Change coordinate axes
213

    
214
  origPoint.x = comX;
215
  origPoint.y = comY; 
216
  origPoint.z = distance;
217

    
218
  // TODO transform into point
219
 
220
  // for now just publish that
221
    
222
  pub.publish(origPoint);
223

    
224
  printf("Ending callback");
225

    
226
}
227

    
228
void target_cb_test(const sensor_msgs::Image image){
229

    
230
        geometry_msgs::Point point;
231
        point.x = 1;
232
        point.y = 2;
233
        point.z = 3;
234
        pub.publish(point);
235
}
236

    
237
int main(int argc, char **argv) {
238
  ros::init(argc, argv, "v2v3_converter");
239
  ros::NodeHandle n;
240
  pub = n.advertise<geometry_msgs::Point>("vision/target_3d", 1000);
241
  img_pub = n.advertise<sensor_msgs::Image>("vision/blob_image", 1000);
242
  ros::Subscriber sub = n.subscribe("/camera/rgb/image_color", 1, target_cb);
243
  ros::spin();
244
  return 0;
245
}