Project

General

Profile

Statistics
| Branch: | Revision:

root / vision / src / v2v3_converter.cpp @ 13b764cd

History | View | Annotate | Download (5.29 KB)

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

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

    
10
int hk = 25; 
11
int sk = 255;
12
int vk = 255;
13

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

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

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

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

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

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

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

    
93
        *area = blobPixelCount;
94
        *comX = comXSum;
95
        *comY = comYSum;
96

    
97
  img_pub.publish(*image);
98
}
99

    
100
void convertToHSV(sensor_msgs::Image * orig){
101
  int nChannels = orig->width / orig->step;
102

    
103
  // get the max, set it as v
104

    
105
  for (int i = 0; i < orig->height * orig->width; i += nChannels){
106
      int h;
107
      int s;
108
      int v; 
109
      int min;
110

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

    
134
      // set s
135
      if (v != 0){
136
      s = (v - min) / v; 
137
      }
138
      else s = 0;
139

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

    
156
  }
157

    
158
}
159

    
160
void target_cb(const sensor_msgs::Image orig) {
161
  tf::TransformListener listener;
162
  geometry_msgs::Point point;
163
  tf::StampedTransform transform;
164
  /*try {
165
    listener.lookupTransform("/camera", "/kinect", ros::Time(0), transform);
166
  }
167
  catch (tf::TransformException ex) {
168
    ROS_ERROR("%s", ex.what());
169
  }*/
170

    
171
  // convert to OpenCV
172

    
173
  sensor_msgs::Image copy = orig;
174
  sensor_msgs::Image * source = &copy; // pointer to the image
175
  sensor_msgs::Image hsvImage = orig; // May be time 
176
  sensor_msgs::Image * hsvPtr = &hsvImage;
177

    
178
  // convert to HSV
179
  
180
  convertToHSV(source);
181

    
182
  // detect blob
183

    
184
  int comX; 
185
  int comY;
186
  int area;
187
  
188
  detectBlobs(hsvPtr, &comX, &comY, &area);
189

    
190
  // give distance as inversely proportional to area, for (x,y,z) 
191
  if (area > 10){
192
    
193
    int distance = 100.0 / (float) area;
194

    
195
    // fill point based on target and tf
196

    
197
    geometry_msgs::Point origPoint;
198

    
199
    origPoint.x = comX;
200
    origPoint.y = comY; 
201
    origPoint.z = distance;
202

    
203
    // TODO transform into point
204
 
205
    // for now just publish that
206

    
207
    pub.publish(origPoint);
208
  }
209
}
210

    
211
int main(int argc, char **argv) {
212
  ros::init(argc, argv, "v2v3_converter");
213
  ros::NodeHandle n;
214
  ros::Subscriber sub = n.subscribe("/camera/rgb/image_color", 1, target_cb);
215
  pub = n.advertise<geometry_msgs::Point>("target_3d", 1000);
216
  img_pub = n.advertise<sensor_msgs::Image>("blob_image", 1000);
217
  ros::spin();
218
  return 0;
219
}