00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef __IMAGEPROCESSORS
00025 #define __IMAGEPROCESSORS
00026
00027 #include "imageprocessor.h"
00028
00029 #include <selforg/stl_adds.h>
00030
00031 #define MIN3(x,y,z) x<y ? (x<z ? x : z) : (y<z ? y : z)
00032 #define MAX3(x,y,z) x>y ? (x>z ? x : z) : (y>z ? y : z)
00033
00034 namespace lpzrobots {
00035
00036
00037
00038
00039
00040
00041
00042
00043 struct StdImageProcessor : public ImageProcessor {
00044 StdImageProcessor(bool show, float scale) {
00045 _dest.show = show;
00046 _dest.scale = scale;
00047 };
00048 virtual ~StdImageProcessor() {
00049 };
00050
00051
00052 virtual void initDestImage(Camera::CameraImage& dest, const Camera::CameraImage& src) = 0;
00053
00054
00055 virtual void process(const osg::Image* src, osg::Image* dest) = 0;
00056
00057
00058 virtual Camera::CameraImage init(const Camera::CameraImages& imgs){
00059 assert(imgs.size()>0);
00060 _src = imgs.back();
00061
00062 _dest.img = new osg::Image;
00063 initDestImage(_dest, _src);
00064 return _dest;
00065 }
00066
00067 virtual void process(){
00068 process(_src.img, _dest.img);
00069 _dest.img->dirty();
00070 }
00071
00072 protected:
00073 Camera::CameraImage _dest;
00074 Camera::CameraImage _src;
00075 };
00076
00077
00078
00079
00080 struct BWImageProcessor : public StdImageProcessor {
00081 enum ChannelMask {Red = 1, Green = 2, Blue = 4, Hue = 1, Saturation = 2, Value = 4};
00082
00083
00084 BWImageProcessor(bool show, float scale, char channelmask = 7)
00085 : StdImageProcessor(show,scale), channelmask(channelmask) {}
00086
00087 virtual ~BWImageProcessor() {}
00088
00089 virtual void initDestImage(Camera::CameraImage& dest, const Camera::CameraImage& src){
00090 dest.img->allocateImage(src.img->s(), src.img->t(), 1, GL_LUMINANCE, GL_UNSIGNED_BYTE);
00091 dest.name = "bw(" + src.name + ")";
00092 red = (channelmask & 1);
00093 green = (channelmask & 2);
00094 blue = (channelmask & 4);
00095 numchannels = red+green+blue;
00096 printf("BWImageProcessor: Select: Red %i, Green %i, Blue %i : numchannels %i\n",
00097 red, green, blue,numchannels);
00098 if(numchannels==0) numchannels=1;
00099 }
00100
00101 virtual void process(const osg::Image* src, osg::Image* dest){
00102 assert(src && src->getPixelFormat()==GL_RGB && src->getDataType()==GL_UNSIGNED_BYTE);
00103 for(int r=0; r < src->t(); ++r) {
00104 const unsigned char* sdata = src->data(0, r);
00105 unsigned char* ddata = dest->data(0, r);
00106 for(int c=0; c < src->s(); ++c) {
00107 (*ddata) = (*(sdata)*red + *(sdata+1)*green + *(sdata+2)*blue)/numchannels;
00108 sdata+=3;
00109 ddata++;
00110 }
00111 }
00112 }
00113 bool red, green, blue;
00114 char numchannels;
00115 char channelmask;
00116 };
00117
00118
00119
00120
00121
00122
00123 struct HSVImgProc : public StdImageProcessor {
00124 enum Colors {Red=0, Yellow=30, Green=60, Cyan=90,
00125 Blue=120, Magenta=150, Red2=180, Gray=255, Span=30};
00126
00127 HSVImgProc(bool show, float scale)
00128 : StdImageProcessor(show,scale) {
00129 }
00130
00131 virtual ~HSVImgProc() {}
00132
00133 virtual void initDestImage(Camera::CameraImage& dest, const Camera::CameraImage& src){
00134 dest.img->allocateImage(src.img->s(), src.img->t(), 1, GL_RGB, GL_UNSIGNED_BYTE);
00135 dest.name = "hsv(" + src.name + ")";
00136 }
00137
00138 virtual void process(const osg::Image* src, osg::Image* dest){
00139 assert(src && src->getPixelFormat()==GL_RGB && src->getDataType()==GL_UNSIGNED_BYTE);
00140 for(int r=0; r < src->t(); ++r) {
00141 const unsigned char* sdata = src->data(0, r);
00142 unsigned char* ddata = dest->data(0, r);
00143 for(int c=0; c < src->s(); ++c) {
00144 RGBtoHSV(*(sdata),*(sdata+1),*(sdata+2),
00145 (*ddata), *(ddata+1), *(ddata+2));
00146 sdata+=3;
00147 ddata+=3;
00148 }
00149 }
00150 }
00151
00152
00153
00154
00155
00156
00157
00158 void RGBtoHSV( unsigned char r, unsigned char g, unsigned char b,
00159 unsigned char& h, unsigned char& s, unsigned char& v ) {
00160 unsigned char min, max;
00161 float delta;
00162 float hue;
00163 min = MIN3( r, g, b );
00164 max = MAX3( r, g, b );
00165 v = max;
00166 delta = max - min;
00167 if( max != 0 ){
00168 s = (unsigned char)(255.0*delta / max);
00169 }
00170 if( max == 0 || delta == 0){
00171
00172 s = 0;
00173 h = 255;
00174 return;
00175 }
00176
00177 if( r == max )
00178 hue = float( g - b ) / delta;
00179 else if( g == max )
00180 hue = 2.0 + float( b - r ) / delta;
00181 else
00182 hue = 4.0 + float( r - g ) / delta;
00183 hue *=30;
00184 if( hue < 0 )
00185 hue += 180;
00186 h = int(hue);
00187 }
00188 };
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 struct ColorFilterImgProc : public StdImageProcessor {
00200 ColorFilterImgProc(bool show, float scale, int minhue, int maxhue,
00201 int sat_threshold=100, int val_threshold=50)
00202 : StdImageProcessor(show,scale),
00203 minhue(minhue), maxhue(maxhue), sat_threshold(sat_threshold), val_threshold(val_threshold) {
00204 }
00205
00206 virtual ~ColorFilterImgProc() {}
00207
00208 virtual void initDestImage(Camera::CameraImage& dest, const Camera::CameraImage& src){
00209 dest.img->allocateImage(src.img->s(), src.img->t(), 1, GL_LUMINANCE, GL_UNSIGNED_BYTE);
00210
00211 dest.name = "spots(" + src.name + ")";
00212 }
00213
00214 virtual void process(const osg::Image* src, osg::Image* dest){
00215
00216 assert(src && src->getPixelFormat()==GL_RGB && src->getDataType()==GL_UNSIGNED_BYTE);
00217 for(int r=0; r < src->t(); ++r) {
00218 const unsigned char* sdata = src->data(0, r);
00219 unsigned char* ddata = dest->data(0, r);
00220 for(int c=0; c < src->s(); ++c) {
00221 if(*(sdata) >= minhue && *(sdata) < maxhue
00222 && *(sdata+1) > sat_threshold && *(sdata+2) > val_threshold){
00223 (*ddata) = *(sdata+2);
00224 } else{
00225 (*ddata) = 0;
00226 }
00227 sdata+=3;
00228 ddata++;
00229 }
00230 }
00231 }
00232 int minhue;
00233 int maxhue;
00234 int sat_threshold;
00235 int val_threshold;
00236 };
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 struct LineImgProc : public StdImageProcessor {
00247 LineImgProc(bool show, float scale, int num, double factor = 20.0)
00248 : StdImageProcessor(show,scale), num(num), factor(factor) {
00249 }
00250
00251 virtual ~LineImgProc() {}
00252
00253 virtual void initDestImage(Camera::CameraImage& dest, const Camera::CameraImage& src){
00254 dest.img->allocateImage(num, 1, 1, GL_LUMINANCE, GL_UNSIGNED_BYTE);
00255 dest.name = "line(" + src.name + ")";
00256 }
00257
00258 virtual void process(const osg::Image* src, osg::Image* dest){
00259
00260 assert(src && src->getPixelFormat()==GL_LUMINANCE && src->getDataType()==GL_UNSIGNED_BYTE);
00261
00262 int w = src->s();
00263 int h = src->t();
00264 int size = w/num;
00265 int numpixel_per_segm = size*h;
00266 int segmentvalue;
00267 unsigned char* destdata = dest->data();
00268 for(int k=0; k<num; k++){
00269 int sum = 0;
00270 for(int j=0; j<h; j++){
00271 const unsigned char* pixel = src->data(k*size, j);
00272 for(int i=0; i< size; i++){
00273 sum += *pixel;
00274 pixel++;
00275 }
00276 }
00277 segmentvalue = int((double)sum*factor/(double)numpixel_per_segm);
00278 destdata[k] = std::min(segmentvalue,255);
00279 }
00280 }
00281 int num;
00282 double factor;
00283 };
00284
00285
00286
00287
00288 struct AvgImgProc : public StdImageProcessor {
00289
00290
00291 AvgImgProc(bool show, float scale, int time)
00292 : StdImageProcessor(show,scale), time(time) {
00293 if(time<1) time =1;
00294 factor = 1.0/(float)time;
00295 }
00296
00297 virtual ~AvgImgProc() {}
00298
00299 virtual void initDestImage(Camera::CameraImage& dest, const Camera::CameraImage& src){
00300 assert(src.img && src.img->getDataType()==GL_UNSIGNED_BYTE);
00301 dest.img->allocateImage(src.img->s(), src.img->t(), 1, src.img->getPixelFormat(),
00302 GL_UNSIGNED_BYTE);
00303 dest.name = "avg(" + std::itos(time) + "," + src.name + ")";
00304 }
00305
00306 virtual void process(const osg::Image* src, osg::Image* dest){
00307 for(int r=0; r < src->t(); ++r) {
00308 const unsigned char* sdata = src->data(0, r);
00309 unsigned char* ddata = dest->data(0, r);
00310 for(unsigned int c=0; c < src->getRowSizeInBytes(); ++c) {
00311 *ddata = (unsigned char)(((float)*sdata)*factor + ((float)*ddata)*(1-factor));
00312 sdata++;
00313 ddata++;
00314 }
00315 }
00316 }
00317
00318 int time;
00319 float factor;
00320 };
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 }
00365
00366 #endif