Difference between revisions of "Example Tracker Mean Shift"
From BoofCV
Jump to navigationJump to search (Created page with "<center> <gallery widths=400px heights=300px> file:Example_tracking_meanshift.jpg | Mean-shift was used to track the ball across this video sequence. </gallery> </center> In ...") |
m |
||
Line 8: | Line 8: | ||
Example Code: | Example Code: | ||
* [https://github.com/lessthanoptimal/BoofCV/blob/v0. | * [https://github.com/lessthanoptimal/BoofCV/blob/v0.18/examples/src/boofcv/examples/tracking/ExampleTrackerMeanShift.java ExampleTrackerMeanShift.java] | ||
Concepts: | Concepts: | ||
Line 22: | Line 22: | ||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
/** | /** | ||
* | * Example of how to use the low level implementation of mean-shift to track a specific color provided by the user. | ||
* | * The weights of each pixel is computed by RgbLikelihood, see below, and track regions are rectangular. This | ||
* tracker works very well since the ball is almost uniformly blue. If the light varried then a HSV color | |||
* | * model might be better. | ||
* | |||
* | * | ||
* @author Peter Abeles | * @author Peter Abeles | ||
*/ | */ | ||
public class | public class ExampleTrackerMeanShiftLikelihood { | ||
/** | |||
* Very simple implementation of PixelLikelihood. Uses linear distance to compute how close | |||
* a color is to the target color. | |||
*/ | |||
public static class RgbLikelihood implements PixelLikelihood<MultiSpectral<ImageUInt8>> { | |||
int targetRed,targetGreen,targetBlue; | |||
float radius = 35; | |||
MultiSpectral<ImageUInt8> image; | |||
public RgbLikelihood(int targetRed, int targetGreen, int targetBlue) { | |||
this.targetRed = targetRed; | |||
this.targetGreen = targetGreen; | |||
this.targetBlue = targetBlue; | |||
} | |||
@Override | |||
public void setImage(MultiSpectral<ImageUInt8> image) { | |||
this.image = image; | |||
} | |||
@Override | |||
public boolean isInBounds(int x, int y) { | |||
return image.isInBounds(x,y); | |||
} | |||
/** | |||
* This function is used to learn the target's model from the select image region. Since the | |||
* model is provided in the constructor it isn't needed or used. | |||
*/ | |||
@Override | |||
public void createModel(RectangleLength2D_I32 target) { | |||
throw new RuntimeException("Not supported"); | |||
} | |||
@Override | |||
public float compute(int x, int y) { | |||
int pixelR = image.getBand(0).get(x,y); | |||
int pixelG = image.getBand(1).get(x,y); | |||
int pixelB = image.getBand(2).get(x,y); | |||
// distance along each color band | |||
float red = Math.max(0, 1.0f - Math.abs(targetRed - pixelR) / radius); | |||
float green = Math.max(0,1.0f - Math.abs(targetGreen-pixelG)/radius); | |||
float blue = Math.max(0,1.0f - Math.abs(targetBlue-pixelB)/radius); | |||
// multiply them all together | |||
return red*green*blue; | |||
} | |||
} | |||
public static void main(String[] args) { | public static void main(String[] args) { | ||
MediaManager media = DefaultMediaManager.INSTANCE; | MediaManager media = DefaultMediaManager.INSTANCE; | ||
String fileName = "../data/applet/tracking/balls_blue_red.mjpeg"; | String fileName = "../data/applet/tracking/balls_blue_red.mjpeg"; | ||
RectangleLength2D_I32 location = new RectangleLength2D_I32(394,247,475-394,325-247); | |||
ImageType<MultiSpectral<ImageUInt8>> imageType = ImageType.ms(3,ImageUInt8.class); | ImageType<MultiSpectral<ImageUInt8>> imageType = ImageType.ms(3,ImageUInt8.class); | ||
Line 40: | Line 91: | ||
SimpleImageSequence<MultiSpectral<ImageUInt8>> video = media.openVideo(fileName, imageType); | SimpleImageSequence<MultiSpectral<ImageUInt8>> video = media.openVideo(fileName, imageType); | ||
// | // Return a higher likelihood for pixels close to this RGB color | ||
RgbLikelihood likelihood = new RgbLikelihood(64,71,69); | |||
TrackerMeanShiftLikelihood<MultiSpectral<ImageUInt8>> tracker = | |||
new TrackerMeanShiftLikelihood<MultiSpectral<ImageUInt8>>(likelihood,50,0.1f); | |||
// specify the target's initial location and initialize with the first frame | // specify the target's initial location and initialize with the first frame | ||
MultiSpectral<ImageUInt8> frame = video.next(); | MultiSpectral<ImageUInt8> frame = video.next(); | ||
// Note that the tracker will not automatically invoke RgbLikelihood.createModel() in its initialize function | |||
tracker.initialize(frame,location); | tracker.initialize(frame,location); | ||
Line 62: | Line 113: | ||
frame = video.next(); | frame = video.next(); | ||
boolean visible = tracker.process(frame | boolean visible = tracker.process(frame); | ||
gui.setBackGround((BufferedImage) video.getGuiImage()); | gui.setBackGround((BufferedImage) video.getGuiImage()); | ||
gui.setTarget( | gui.setTarget(tracker.getLocation(),visible); | ||
gui.repaint(); | gui.repaint(); | ||
Revision as of 14:14, 22 September 2014
In this example mean-shift is used to track a color ball. Mean-shift performs a local search that attempts to maximize the similarity of the color in its kernel to the color in its model. It is a fairly robust and fast tracker. If you are lucky, it will sometimes even reaquire a track after it has been lost.
Example Code:
Concepts:
- Object tracking
- Color histogram
- Mean-shift
Relevant Applets:
Example Code
/**
* Example of how to use the low level implementation of mean-shift to track a specific color provided by the user.
* The weights of each pixel is computed by RgbLikelihood, see below, and track regions are rectangular. This
* tracker works very well since the ball is almost uniformly blue. If the light varried then a HSV color
* model might be better.
*
* @author Peter Abeles
*/
public class ExampleTrackerMeanShiftLikelihood {
/**
* Very simple implementation of PixelLikelihood. Uses linear distance to compute how close
* a color is to the target color.
*/
public static class RgbLikelihood implements PixelLikelihood<MultiSpectral<ImageUInt8>> {
int targetRed,targetGreen,targetBlue;
float radius = 35;
MultiSpectral<ImageUInt8> image;
public RgbLikelihood(int targetRed, int targetGreen, int targetBlue) {
this.targetRed = targetRed;
this.targetGreen = targetGreen;
this.targetBlue = targetBlue;
}
@Override
public void setImage(MultiSpectral<ImageUInt8> image) {
this.image = image;
}
@Override
public boolean isInBounds(int x, int y) {
return image.isInBounds(x,y);
}
/**
* This function is used to learn the target's model from the select image region. Since the
* model is provided in the constructor it isn't needed or used.
*/
@Override
public void createModel(RectangleLength2D_I32 target) {
throw new RuntimeException("Not supported");
}
@Override
public float compute(int x, int y) {
int pixelR = image.getBand(0).get(x,y);
int pixelG = image.getBand(1).get(x,y);
int pixelB = image.getBand(2).get(x,y);
// distance along each color band
float red = Math.max(0, 1.0f - Math.abs(targetRed - pixelR) / radius);
float green = Math.max(0,1.0f - Math.abs(targetGreen-pixelG)/radius);
float blue = Math.max(0,1.0f - Math.abs(targetBlue-pixelB)/radius);
// multiply them all together
return red*green*blue;
}
}
public static void main(String[] args) {
MediaManager media = DefaultMediaManager.INSTANCE;
String fileName = "../data/applet/tracking/balls_blue_red.mjpeg";
RectangleLength2D_I32 location = new RectangleLength2D_I32(394,247,475-394,325-247);
ImageType<MultiSpectral<ImageUInt8>> imageType = ImageType.ms(3,ImageUInt8.class);
SimpleImageSequence<MultiSpectral<ImageUInt8>> video = media.openVideo(fileName, imageType);
// Return a higher likelihood for pixels close to this RGB color
RgbLikelihood likelihood = new RgbLikelihood(64,71,69);
TrackerMeanShiftLikelihood<MultiSpectral<ImageUInt8>> tracker =
new TrackerMeanShiftLikelihood<MultiSpectral<ImageUInt8>>(likelihood,50,0.1f);
// specify the target's initial location and initialize with the first frame
MultiSpectral<ImageUInt8> frame = video.next();
// Note that the tracker will not automatically invoke RgbLikelihood.createModel() in its initialize function
tracker.initialize(frame,location);
// For displaying the results
TrackerObjectQuadPanel gui = new TrackerObjectQuadPanel(null);
gui.setPreferredSize(new Dimension(frame.getWidth(),frame.getHeight()));
gui.setBackGround((BufferedImage)video.getGuiImage());
gui.setTarget(location,true);
ShowImages.showWindow(gui, "Tracking Results");
// Track the object across each video frame and display the results
while( video.hasNext() ) {
frame = video.next();
boolean visible = tracker.process(frame);
gui.setBackGround((BufferedImage) video.getGuiImage());
gui.setTarget(tracker.getLocation(),visible);
gui.repaint();
BoofMiscOps.pause(20);
}
}
}