Example Background Moving Camera
From BoofCV
Jump to navigationJump to searchThe printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
In this example the objects which are moving relative to the background are highlighted in a binary image. While much slower than background modeling for static cameras, it can handle gradual camera motion when viewing environments that are approximately planar or being viewed for a distance. If the same videos were feed into a static camera background motion the entire image would be lit up as moving.
Example File:
Concepts:
- Motion Detection
- 2D Image Stitching
Related Examples:
Example Code
/**
* Example showing how to perform background modeling with a moving camera. Here the camera's motion is explicitly
* estimated using a motion model. That motion model is then used to distort the image and generate background.
* The net affect is a significant reduction in false positives around the objects of images in oscillating cameras
* and the ability to detect motion in moving scenes.
*
* @author Peter Abeles
*/
public class ExampleBackgroundRemovalMoving {
public static void main(String[] args) {
// Example with a moving camera. Highlights why motion estimation is sometimes required
String fileName = UtilIO.pathExample("tracking/chipmunk.mjpeg");
// Camera has a bit of jitter in it. Static kinda works but motion reduces false positives
// String fileName = UtilIO.pathExample("background/horse_jitter.mp4");
// Comment/Uncomment to switch input image type
ImageType imageType = ImageType.single(GrayF32.class);
// ImageType imageType = ImageType.il(3, InterleavedF32.class);
// ImageType imageType = ImageType.il(3, InterleavedU8.class);
// Configure the feature detector
ConfigGeneralDetector confDetector = new ConfigGeneralDetector();
confDetector.threshold = 10;
confDetector.maxFeatures = 300;
confDetector.radius = 6;
// Use a KLT tracker
PointTracker tracker = FactoryPointTracker.klt(new int[]{1, 2, 4, 8}, confDetector, 3,
GrayF32.class, null);
// This estimates the 2D image motion
ImageMotion2D<GrayF32,Homography2D_F64> motion2D =
FactoryMotion2D.createMotion2D(500, 0.5, 3, 100, 0.6, 0.5, false, tracker, new Homography2D_F64());
ConfigBackgroundBasic configBasic = new ConfigBackgroundBasic(30, 0.005f);
// Configuration for Gaussian model. Note that the threshold changes depending on the number of image bands
// 12 = gray scale and 40 = color
ConfigBackgroundGaussian configGaussian = new ConfigBackgroundGaussian(12,0.001f);
configGaussian.initialVariance = 64;
configGaussian.minimumDifference = 5;
// Comment/Uncomment to switch background mode
BackgroundModelMoving background =
FactoryBackgroundModel.movingBasic(configBasic, new PointTransformHomography_F32(), imageType);
// FactoryBackgroundModel.movingGaussian(configGaussian, new PointTransformHomography_F32(), imageType);
MediaManager media = DefaultMediaManager.INSTANCE;
SimpleImageSequence video =
media.openVideo(fileName, background.getImageType());
// media.openCamera(null,640,480,background.getImageType());
//====== Initialize Images
// storage for segmented image. Background = 0, Foreground = 1
GrayU8 segmented = new GrayU8(video.getNextWidth(),video.getNextHeight());
// Grey scale image that's the input for motion estimation
GrayF32 grey = new GrayF32(segmented.width,segmented.height);
// coordinate frames
Homography2D_F32 firstToCurrent32 = new Homography2D_F32();
Homography2D_F32 homeToWorld = new Homography2D_F32();
homeToWorld.a13 = grey.width/2;
homeToWorld.a23 = grey.height/2;
// Create a background image twice the size of the input image. Tell it that the home is in the center
background.initialize(grey.width * 2, grey.height * 2, homeToWorld);
BufferedImage visualized = new BufferedImage(segmented.width,segmented.height,BufferedImage.TYPE_INT_RGB);
ImageGridPanel gui = new ImageGridPanel(1,2);
gui.setImages(visualized, visualized);
ShowImages.showWindow(gui, "Detections", true);
double fps = 0;
double alpha = 0.01; // smoothing factor for FPS
while( video.hasNext() ) {
ImageBase input = video.next();
long before = System.nanoTime();
GConvertImage.convert(input, grey);
if( !motion2D.process(grey) ) {
throw new RuntimeException("Should handle this scenario");
}
Homography2D_F64 firstToCurrent64 = motion2D.getFirstToCurrent();
UtilHomography.convert(firstToCurrent64, firstToCurrent32);
background.segment(firstToCurrent32, input, segmented);
background.updateBackground(firstToCurrent32,input);
long after = System.nanoTime();
fps = (1.0-alpha)*fps + alpha*(1.0/((after-before)/1e9));
VisualizeBinaryData.renderBinary(segmented,false,visualized);
gui.setImage(0, 0, (BufferedImage)video.getGuiImage());
gui.setImage(0, 1, visualized);
gui.repaint();
System.out.println("FPS = "+fps);
try {Thread.sleep(5);} catch (InterruptedException e) {}
}
}
}