00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <signal.h>
00037 #include <stdlib.h>
00038 #include <math.h>
00039 #include <ctype.h>
00040 #include <time.h>
00041
00042 #include "opencv/cv.h"
00043 #include "opencv/cvaux.h"
00044 #include "opencv/highgui.h"
00045 #include "opencv/cxcore.h"
00046
00047 #include "ros/node_handle.h"
00048
00049 #include "std_msgs/UInt8.h"
00050
00051 #include "limits.h"
00052
00053 #include <iostream>
00054
00055 #define WD 1280
00056 #define HT 1024
00057 #define BLOCK_SIZE 2
00058 #define MAX_BLOCK_SIZE 128
00059 #define MIN_BLOCK_SIZE 1
00060
00061
00062 inline int min(int a, int b){
00063 return (a<b)?a:b;
00064 }
00065
00066
00067 bool BlankScreen = true;
00068 bool BlankScreenPrevious = false;
00069 IplImage* Rbp;
00070 IplImage* BlankImage;
00071 IplImage *current;
00072
00073 std_msgs::UInt8 status_out;
00074
00075 using namespace std;
00076
00077 class LightProjector : public ros::NodeHandle
00078 {
00079 public:
00080 int alt2_on1_off0;
00081 int _offset, _range, _block_size;
00082 bool _ramp;
00083 float ffactor;
00084
00085 LightProjector(ros::NodeHandle &n) : alt2_on1_off0(1), _offset(0), _range(128), _block_size(BLOCK_SIZE), _ramp(false), ffactor(1.0), n_(n)
00086 {
00087 n_.param("frequency", frequency, 1.0);
00088 n_.setParam("pattern_on", 1);
00089 cout << "frequency = " << frequency << endl;
00090 status_publisher = n_.advertise<std_msgs::UInt8>("projector_status", 10);
00091 }
00092
00093
00094
00095
00096
00097
00098 void grayscale_rbp(IplImage *rbp, int offset = 0, int range = 128, int block_size = BLOCK_SIZE, bool ramp = false){
00099 printf("Pattern: offset(%d), range(%d), block_size(%d), ramp(%d)\n",offset,range,block_size,ramp);
00100 int w = rbp->width;
00101 int h = rbp->height;
00102 int ws = rbp->widthStep;
00103 unsigned char *drbp = ((unsigned char *)(rbp->imageData));
00104
00105 int i,j,x,y, rn;
00106 int bs = block_size;
00107 float ramp_down_step = 0.5*(float)range/(float)h;
00108 int ramp_down = 0;
00109
00110
00111 for(y=0; y<h; y+=bs){
00112 for(x=0; x<w; x+=bs){
00113
00114 rn = (rand()%range)+offset;
00115 if(ramp) {
00116 ramp_down = (int)(ramp_down_step*(float)y);
00117 rn -= ramp_down;
00118 }
00119 if(rn < 0) rn = 0;
00120 if(rn > 255) rn = 255;
00121
00122
00123 for(j=0; j<bs; j++){
00124 for(i=0; i<bs; i++){
00125 drbp[(y+j)*ws+x+i] = rn;
00126 }
00127 }
00128 }
00129 }
00130 }
00131
00132 bool spin()
00133 {
00134 int key = 'a';
00135 while (ok())
00136 {
00137 getParam("pattern_on", alt2_on1_off0);
00138 key = cvWaitKey(10)&0xFF;
00139 if(key == 27 )
00140 break;
00141 switch(key)
00142 {
00143 case 'h':
00144 cout << "\nNode to flip projector pattern on and off\n" << endl;
00145 cout << " a,1,0 a,2:Alternate projector pattern, 1:On, 0:Off" << endl;
00146 cout << " o,O offset down, up" << endl;
00147 cout << " r,R range down, up" << endl;
00148 cout << " b,B block_size down, up" << endl;
00149 cout << " d dim bottom of image toggle" << endl;
00150 cout << "--------\n" << endl;
00151 break;
00152 case '0':
00153 alt2_on1_off0 = 0;
00154 ffactor = 40.0;
00155 break;
00156 case '1':
00157 alt2_on1_off0 = 1;
00158 ffactor = 40.0;
00159 break;
00160 case 'a':
00161 case '2':
00162 alt2_on1_off0 = 2;
00163 ffactor = 1.0;
00164 break;
00165
00166 case 'o':
00167 _offset -= 10;
00168 if(_offset < -255) _offset = -255;
00169 printf("New Pattern: offset(%d), range(%d), block_size(%d), ramp(%d)\n",_offset,_range,_block_size,_ramp);
00170 grayscale_rbp(Rbp, _offset, _range, _block_size, _ramp);
00171 break;
00172 case 'O':
00173 _offset += 10;
00174 if(_offset > 255) _offset = 255;
00175 printf("New Pattern: offset(%d), range(%d), block_size(%d), ramp(%d)\n",_offset,_range,_block_size,_ramp);
00176 grayscale_rbp(Rbp, _offset, _range, _block_size, _ramp);
00177 break;
00178 case 'r':
00179 _range -= 10;
00180 if(_range < 10) _range = 10;
00181 printf("New Pattern: offset(%d), range(%d), block_size(%d), ramp(%d)\n",_offset,_range,_block_size,_ramp);
00182 grayscale_rbp(Rbp, _offset, _range, _block_size, _ramp);
00183 break;
00184 case 'R':
00185 _range += 10;
00186 if(_range > 255) _range = 400;
00187 printf("New Pattern: offset(%d), range(%d), block_size(%d), ramp(%d)\n",_offset,_range,_block_size,_ramp);
00188 grayscale_rbp(Rbp, _offset, _range, _block_size, _ramp);
00189 break;
00190 case 'b':
00191 _block_size /= 2;
00192 if(_block_size <= 0) _block_size = MIN_BLOCK_SIZE;
00193 printf("New Pattern: offset(%d), range(%d), block_size(%d), ramp(%d)\n",_offset,_range,_block_size,_ramp);
00194 grayscale_rbp(Rbp, _offset, _range, _block_size, _ramp);
00195 break;
00196 case 'B':
00197 _block_size *= 2;
00198 if(_block_size > 80) _block_size = MAX_BLOCK_SIZE;
00199 printf("New Pattern: offset(%d), range(%d), block_size(%d), ramp(%d)\n",_offset,_range,_block_size,_ramp);
00200 grayscale_rbp(Rbp, _offset, _range, _block_size, _ramp);
00201 break;
00202 case 'd':
00203 _ramp = !_ramp;
00204 printf("New Pattern: offset(%d), range(%d), block_size(%d), ramp(%d)\n",_offset,_range,_block_size,_ramp);
00205 grayscale_rbp(Rbp, _offset, _range, _block_size, _ramp);
00206 break;
00207 case 's':
00208 cvSaveImage("pattern.png", Rbp);
00209 ROS_INFO("Saved image pattern.png");
00210 break;
00211 }
00212
00213
00214 if(alt2_on1_off0 == 2)
00215 {
00216 if(!BlankScreen){
00217 cvShowImage("RBP Projector", Rbp);
00218 }
00219 else{
00220 cvShowImage("RBP Projector", BlankImage);
00221 }
00222 }
00223
00224 else if(alt2_on1_off0 == 1) {
00225 cvShowImage("RBP Projector", Rbp);
00226 BlankScreen = 1;
00227 }
00228
00229 else {
00230 cvShowImage("RBP Projector", BlankImage);
00231 BlankScreen = 0;
00232 }
00233
00234 usleep(1000000.0/(frequency*ffactor));
00235 if(alt2_on1_off0 == 2) BlankScreen = !BlankScreen;
00236 status_out.data = (int)BlankScreen;
00237
00238 status_publisher.publish(status_out);
00239
00240 }
00241 return true;
00242 }
00243
00244 private:
00245 double frequency;
00246 ros::Publisher status_publisher;
00247 ros::NodeHandle n_;
00248 };
00249
00250 int main(int argc, char **argv){
00251 for(int i = 0; i<argc; ++i)
00252 cout << "(" << i << "): " << argv[i] << endl;
00253 ros::init(argc, argv, "light_projector");
00254 ros::NodeHandle n("~");
00255 LightProjector LP(n);
00256
00257 Rbp = cvCreateImage(cvSize(WD,HT), 8, 1);
00258 BlankImage = cvCreateImage(cvSize(WD,HT), 8, 1);
00259 for(int j=0; j<BlankImage->height; j++)
00260 for(int i=0; i<BlankImage->width; i++)
00261 ((unsigned char *)(BlankImage->imageData))[j*BlankImage->widthStep+i] = 0;
00262
00263 cvNamedWindow("RBP Projector", 0);
00264 cvResizeWindow("RBP Projector", WD, HT);
00265 cvMoveWindow("RBP Projector", 0, 0);
00266
00267 cvShowImage("RBP Projector", BlankImage);
00268
00269 LP.grayscale_rbp(Rbp);
00270
00271 srand ( time(NULL) );
00272
00273 LP.spin();
00274
00275 cvReleaseImage(&Rbp);
00276 cvReleaseImage(&BlankImage);
00277 cvDestroyWindow("RBP Projector");
00278
00279 return 0;
00280
00281 }
00282
00283