package pool.utils;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;

import pool.app.Calibration;
import pool.tests.ColorSpace;

public class BackgroundSubtractor {
	private Calibration calib;

	public BackgroundSubtractor(Calibration calib) {
		this.calib = calib;
	}
	
	public Mat createMask(Mat camera) {				
		// copy as we are going to destruct those images maybe
		Mat camBlur= camera.clone();
		Mat backgroundBlur = calib.getBackgroundImage().clone();

		// remove noise
		Imgproc.blur(backgroundBlur, backgroundBlur, new Size(calib.getBlurSize(), calib.getBlurSize()));
		Imgproc.blur(camBlur, camBlur, new Size(calib.getBlurSize(), calib.getBlurSize()));

		// take abs diff and create binary image in all 3 channels
		Mat diff = new Mat();
		Core.absdiff(backgroundBlur, camBlur, diff);
		Imgproc.threshold(diff, diff, calib.getSubtractionThreshold(), 255, Imgproc.THRESH_BINARY);

		// extract color channels and merge them to single bitmask
		Mat r = ColorSpace.getChannel(diff, 2);
		Mat g = ColorSpace.getChannel(diff, 1);
		Mat b = ColorSpace.getChannel(diff, 0);

		Mat mask = r.clone();
		Core.add(mask, g, mask);
		Core.add(mask, b, mask);
		
		// dilate to remove some black gaps within balls
		Imgproc.dilate(mask, mask, Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(calib.getMorphSize(), calib.getMorphSize())));

		return mask;
	}
}