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 }