/*
* Copyright (c) 2011-2016, Peter Abeles. All Rights Reserved.
*
* This file is part of BoofCV (http://boofcv.org).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package boofcv.alg.background.stationary;
import boofcv.alg.misc.GImageMiscOps;
import boofcv.alg.misc.ImageMiscOps;
import boofcv.struct.image.GrayU8;
import boofcv.struct.image.ImageBase;
import boofcv.struct.image.ImageType;
import boofcv.testing.BoofTesting;
import org.junit.Before;
import org.junit.Test;
/**
* @author Peter Abeles
*/
public abstract class GenericBackgroundStationaryGaussianChecks extends GenericBackgroundModelStationaryChecks {
float initialVariance;
@Before
public void init() {
initialVariance = 12;
}
@Test
public void initialVariance() {
for( ImageType type : imageTypes ) {
initialVariance(type);
}
}
private <T extends ImageBase> void initialVariance( ImageType<T> imageType ) {
this.initialVariance = Float.NaN; // turn off setting it
BackgroundStationaryGaussian<T> alg = (BackgroundStationaryGaussian)create(imageType);
alg.setThreshold(10);
GrayU8 segmented = new GrayU8(width,height);
GrayU8 expected = new GrayU8(width,height);
T frame = imageType.createImage(width,height);
GImageMiscOps.fill(frame,20);
alg.updateBackground(frame);
// the initial variance should be zero, which means any small change should be motion
ImageMiscOps.fill(expected, 0);
alg.segment(frame, segmented);
BoofTesting.assertEquals(expected, segmented, 1e-5f);
ImageMiscOps.fill(expected, 1);
GImageMiscOps.fill(frame, 21);
alg.segment(frame, segmented);
BoofTesting.assertEquals(expected, segmented, 1e-5f);
// try giving it a larger initial variance
alg.setInitialVariance(10);
alg.reset();
GImageMiscOps.fill(frame, 20);
alg.updateBackground(frame);
ImageMiscOps.fill(expected, 0);
alg.segment(frame, segmented);
BoofTesting.assertEquals(expected, segmented, 1e-5f);
GImageMiscOps.fill(frame, 21);
alg.segment(frame, segmented);
BoofTesting.assertEquals(expected, segmented, 1e-5f);
ImageMiscOps.fill(expected, 1);
GImageMiscOps.fill(frame, 100);
alg.segment(frame, segmented);
BoofTesting.assertEquals(expected, segmented, 1e-5f);
}
@Test
public void learnRate() {
for( ImageType type : imageTypes ) {
checkLearnRate_slow(type);
checkLearnRate_fast(type);
}
}
private <T extends ImageBase> void checkLearnRate_slow(ImageType<T> imageType) {
BackgroundStationaryGaussian<T> alg = (BackgroundStationaryGaussian)create(imageType);
alg.setThreshold(10);
alg.setInitialVariance(64);
T frame = imageType.createImage(width,height);
// learn very slow. Should virtually ignore new images with different model
alg.setLearnRate(0.01f);
for (int i = 0; i < 30; i++) {
noise(100, 2, frame);
alg.updateBackground(frame);
}
for (int i = 0; i < 3; i++) {
noise(150, 2, frame);
alg.updateBackground(frame);
}
GrayU8 segmented = new GrayU8(width,height);
GrayU8 expected = new GrayU8(width,height);
alg.segment(frame,segmented);
ImageMiscOps.fill(expected, 1);
BoofTesting.assertEquals(expected,segmented,1e-5f);
}
private <T extends ImageBase> void checkLearnRate_fast(ImageType<T> imageType) {
BackgroundStationaryGaussian<T> alg = (BackgroundStationaryGaussian)create(imageType);
alg.setThreshold(10);
alg.setInitialVariance(64);
T frame = imageType.createImage(width,height);
// learn very fast. will quickly discard old images and use the new ones
alg.setLearnRate(0.99f);
for (int i = 0; i < 30; i++) {
noise(100, 2, frame);
alg.updateBackground(frame);
}
for (int i = 0; i < 3; i++) {
noise(150, 2, frame);
alg.updateBackground(frame);
}
GrayU8 segmented = new GrayU8(width,height);
GrayU8 expected = new GrayU8(width,height);
alg.segment(frame,segmented);
ImageMiscOps.fill(expected, 0);
BoofTesting.assertEquals(expected,segmented,1e-5f);
}
@Test
public void minimumDifference() {
for( ImageType type : imageTypes ) {
minimumDifference(type);
}
}
private <T extends ImageBase> void minimumDifference( ImageType<T> imageType ) {
BackgroundStationaryGaussian<T> alg = (BackgroundStationaryGaussian)create(imageType);
alg.setThreshold(10);
alg.setInitialVariance(0);
GrayU8 segmented = new GrayU8(width,height);
GrayU8 expected = new GrayU8(width,height);
T frame = imageType.createImage(width,height);
GImageMiscOps.fill(frame, 20);
alg.updateBackground(frame);
// Turn off minimum difference
alg.setMinimumDifference(0);
GImageMiscOps.fill(frame, 21);
alg.segment(frame, segmented);
ImageMiscOps.fill(expected, 1);
BoofTesting.assertEquals(expected, segmented, 1e-5f);
// Turn it on and check
alg.setMinimumDifference(4);
GImageMiscOps.fill(frame, 21);
alg.segment(frame, segmented);
ImageMiscOps.fill(expected, 0);
BoofTesting.assertEquals(expected, segmented, 1e-5f);
GImageMiscOps.fill(frame, 23);
alg.segment(frame, segmented);
BoofTesting.assertEquals(expected, segmented, 1e-5f);
GImageMiscOps.fill(frame, 24); // test a value just after the threshold
alg.segment(frame, segmented);
ImageMiscOps.fill(expected, 1);
BoofTesting.assertEquals(expected, segmented, 1e-5f);
}
}