test-MotionSegment.C

00001 #include "Component/ModelManager.H"
00002 #include "Media/FrameSeries.H"
00003 #include "Transport/FrameIstream.H"
00004 #include "RCBot/Motion/MotionEnergy.H"
00005 #include "Image/ColorOps.H"
00006 #include "Gist/SuperPixel.H"
00007 #include "Image/ShapeOps.H"
00008 #include "Image/Kernels.H"
00009 #include "Image/Convolver.H"
00010 
00011 #include "Image/LowPass.H"
00012 #include "Image/Image.H"
00013 #include "Image/Pixels.H"
00014 #include "Raster/Raster.H"
00015 #include "Image/CutPaste.H"     // for inplacePaste()
00016 #include "Image/LowPass.H"
00017 
00018 int main(int argc, char **argv)
00019 {
00020 
00021   // instantiate a model manager:
00022   ModelManager manager("Test Motion Segment");
00023 
00024   nub::soft_ref<InputFrameSeries> ifs(new InputFrameSeries(manager));
00025   manager.addSubComponent(ifs);
00026 
00027   nub::soft_ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager));
00028   manager.addSubComponent(ofs);
00029 
00030   manager.exportOptions(MC_RECURSE);
00031 
00032   // Parse command-line:
00033   if (manager.parseCommandLine(argc, argv, "" "", 0, 0) == false) return(1);
00034 
00035   // let's do it!
00036   manager.start();
00037 
00038 
00039   int magthresh = 150;
00040   int pyrlevel = 1;
00041   MotionEnergyPyrBuilder<byte> motionPyr(Gaussian5, 0.0f, 10.0f, 3,
00042                                          magthresh);
00043   
00044 
00045   ifs->updateNext();
00046   Image<PixRGB<byte> > ima = ifs->readRGB();
00047   while(ima.initialized())
00048   {
00049     // Calculate horizontal and vertical motion vectors using a temporal sobel filter
00050     Image<byte> lum = luminance(ima);
00051     motionPyr.updateMotion(lum, pyrlevel+1);
00052     Image<float> vMotion = motionPyr.buildVerticalMotionLevel(pyrlevel);
00053     Image<float> hMotion = motionPyr.buildHorizontalMotionLevel(pyrlevel);
00054     Image<float> motionDir(vMotion.getDims(), NO_INIT);
00055     Image<float> motionMag(vMotion.getDims(), NO_INIT);
00056 
00057     // Calculate the motion magnitude and direction from the vertical and
00058     // horizontal motion vectors
00059     for(size_t i=0; i<vMotion.size(); i++)
00060     {
00061       motionDir.setVal(i, atan2(vMotion.getVal(i), hMotion.getVal(i)));
00062       motionMag.setVal(i, sqrt(pow(vMotion.getVal(i),2)+ pow(hMotion.getVal(i),2)));
00063     }
00064     motionDir = rescaleBilinear(motionDir, ima.getDims());
00065     motionMag = rescaleBilinear(motionMag, ima.getDims());
00066 
00067     // Blur the motion magnitude and direction like crazy
00068     Image<float> motionGaussian = gaussian<float>(0.0F, 8.0F, 0, 1.0F);
00069     motionDir = sepFilter(motionDir, motionGaussian, motionGaussian, CONV_BOUNDARY_REPLICATE);
00070     motionMag = sepFilter(motionMag, motionGaussian, motionGaussian, CONV_BOUNDARY_REPLICATE);
00071     motionDir *= motionMag;
00072 
00073     motionDir *= 200.0;
00074     motionMag *= 200.0;
00075 
00076     Image<float> motionDirNorm = motionDir; 
00077     Image<float> motionMagNorm = motionMag; 
00078 
00079     // Create a fake RGB image using the motion direction and magnitude as channels
00080     Image<PixRGB<byte> > motionFeatures(motionDir.getDims(), NO_INIT);
00081     for(size_t i=0; i<motionFeatures.size(); i++)
00082     {
00083       PixRGB<byte> features(motionDirNorm.getVal(i), motionMagNorm.getVal(i), 0);
00084       motionFeatures.setVal(i, features);
00085     }
00086 
00087     // Segment the fake RGB image using SuperPixel
00088     std::vector<std::vector<Point2D<int> > > groups;
00089     int num_ccs = 0;
00090     float sigma = .4;
00091     int k=1500;
00092     int minSize=600;
00093     Image<int> groupImage = SuperPixelSegment(motionFeatures, sigma, k, minSize, num_ccs, &groups);
00094 
00095     
00096     // Find the groups with high motion energy, and draw a convex hull around them
00097     Image<PixRGB<byte> > outputImage = ima;
00098     for(size_t i=0; i<groups.size(); i++)
00099     {
00100       double totalMotion = 0;
00101       std::vector<Point2D<float> > floatPoly;
00102       for(size_t j=0; j<groups[i].size(); j++)
00103       {
00104         totalMotion += motionMag.getVal(groups[i][j]);
00105         Point2D<float> p;
00106         p.i = groups[i][j].i;
00107         p.j = groups[i][j].j;
00108         floatPoly.push_back(p);
00109       }
00110 
00111       if(totalMotion/double(groups[i].size()) < 5.0) continue;
00112 
00113       std::vector<Point2D<float> > poly = approximateHull(floatPoly, 30);
00114       std::vector<Point2D<int> > intPoly;
00115       for(size_t j=0; j<poly.size(); j++)
00116       {
00117         Point2D<int> p;
00118         p.i = poly[j].i;
00119         p.j = poly[j].j;
00120         intPoly.push_back(p);
00121       }
00122       drawOutlinedPolygon(outputImage, intPoly, PixRGB<byte>(255,0,0));
00123     }
00124 
00125     ofs->writeRGB(motionFeatures, "Features");
00126     ofs->writeRGB(SuperPixelDebugImage(groups, ima), "SuperPixel");
00127     ofs->writeRGB(motionDir, "Motion Direction");
00128     ofs->writeRGB(motionMag, "Motion Magnitude");
00129     ofs->writeRGB(outputImage, "SuperPixel Segmentation");
00130     ofs->updateNext();
00131     ima = ifs->readRGB();
00132   }
00133 
00134   return 0;
00135 }
Generated on Sun May 8 08:04:48 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3