package com.shootoff.camera.perspective;
import static org.junit.Assert.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import javax.imageio.ImageIO;
import org.junit.Before;
import org.junit.Test;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint2f;
import org.opencv.imgproc.Imgproc;
import com.shootoff.camera.MockCamera;
import com.shootoff.camera.MockCameraManager;
import com.shootoff.camera.TestAutoCalibration;
import com.shootoff.camera.autocalibration.AutoCalibrationManager;
import com.shootoff.camera.cameratypes.Camera;
import com.shootoff.camera.perspective.PerspectiveManager;
import com.shootoff.config.ConfigurationException;
import javafx.geometry.BoundingBox;
import javafx.geometry.Dimension2D;
public class TestPerspectiveManager {
private AutoCalibrationManager acm;
@Before
public void setUp() throws ConfigurationException {
nu.pattern.OpenCV.loadShared();
acm = new AutoCalibrationManager(new MockCameraManager(), new MockCamera(), false);
}
@Test
public void testOne() throws ConfigurationException {
assertTrue(PerspectiveManager.isCameraSupported("C270", new Dimension2D(1280, 720)));
PerspectiveManager pm = new PerspectiveManager("C270", new Dimension2D(1280, 720), new BoundingBox(0, 0, 736, 544));
pm.setCameraFeedSize(1280, 720);
pm.setCameraDistance(3406);
pm.setShooterDistance(3406);
pm.setProjectorResolution(1024, 768);
pm.calculateUnknown();
assertEquals(1753.0, pm.getProjectionWidth(), 1);
assertEquals(1299.0, pm.getProjectionHeight(), 1);
Optional<Dimension2D> dims = pm.calculateObjectSize(300, 200, 3406);
assertTrue(dims.isPresent());
assertEquals(175.3, dims.get().getWidth(), 1);
assertEquals(118.2, dims.get().getHeight(), 1);
dims = pm.calculateObjectSize(300, 200, 3406*2);
assertTrue(dims.isPresent());
assertEquals(87.7, dims.get().getWidth(), 1);
assertEquals(59.1, dims.get().getHeight(), 1);
dims = pm.calculateObjectSize(300, 200, 3406 / 2);
assertTrue(dims.isPresent());
assertEquals(350.7, dims.get().getWidth(), 1);
assertEquals(236.5, dims.get().getHeight(), 1);
pm.setShooterDistance(3406 * 2);
dims = pm.calculateObjectSize(300, 200, 3406);
assertTrue(dims.isPresent());
assertEquals(350.7, dims.get().getWidth(), 1);
assertEquals(236.5, dims.get().getHeight(), 1);
}
@Test
public void testTwo() throws ConfigurationException {
PerspectiveManager pm = new PerspectiveManager(new BoundingBox(0, 0, 422, 316));
pm.setCameraParameters(4, 3.125, 2.32);
pm.setCameraFeedSize(640, 480);
pm.setCameraDistance(3406);
pm.setShooterDistance(3406);
pm.setProjectorResolution(1024, 768);
pm.calculateUnknown();
assertEquals(1753.0, pm.getProjectionWidth(), 1);
assertEquals(1299.0, pm.getProjectionHeight(), 1);
Optional<Dimension2D> dims = pm.calculateObjectSize(300, 200, 3406);
assertTrue(dims.isPresent());
assertEquals(175.3, dims.get().getWidth(), 1);
assertEquals(118.2, dims.get().getHeight(), 1);
}
@Test
public void testThree() throws ConfigurationException {
PerspectiveManager pm = new PerspectiveManager(new BoundingBox(0, 0, 422, 316));
pm.setProjectionSize(1753, 1299);
pm.setCameraFeedSize(640, 480);
pm.setCameraDistance(3406);
pm.setShooterDistance(3406);
pm.setProjectorResolution(1024, 768);
pm.calculateUnknown();
assertEquals(4, pm.getFocalLength(), 1);
assertEquals(3.122, pm.getSensorWidth(), .01);
assertEquals(2.317, pm.getSensorHeight(), .01);
Optional<Dimension2D> dims = pm.calculateObjectSize(300, 200, 3406);
assertTrue(dims.isPresent());
assertEquals(175.3, dims.get().getWidth(), 1);
assertEquals(118.2, dims.get().getHeight(), 1);
}
@Test
public void testPaperPixelsCalcParams() throws ConfigurationException {
PerspectiveManager pm = new PerspectiveManager(new BoundingBox(0, 0, 422, 316), new Dimension2D(640, 480),
new Dimension2D(67, 53), new Dimension2D(1024, 768));
pm.setCameraDistance(3498);
pm.setShooterDistance(3498);
pm.calculateUnknown();
assertEquals(4, pm.getFocalLength(), 1);
assertEquals(3.047, pm.getSensorWidth(), .01);
assertEquals(2.235, pm.getSensorHeight(), .01);
Optional<Dimension2D> dims = pm.calculateObjectSize(279, 216, pm.getCameraDistance());
assertTrue(dims.isPresent());
assertEquals(162.6, dims.get().getWidth(), 1);
assertEquals(128.9, dims.get().getHeight(), 1);
}
@Test
public void testPaperPattern() throws IOException {
BufferedImage testFrame = ImageIO
.read(TestAutoCalibration.class.getResourceAsStream("/perspective/c270_pattern_new.png"));
Mat matTemp = Camera.bufferedImageToMat(testFrame);
final Mat mat = new Mat();
Imgproc.cvtColor(matTemp, mat, Imgproc.COLOR_BGR2GRAY);
final Optional<MatOfPoint2f> boardCorners = acm.findChessboard(mat);
assertTrue(boardCorners.isPresent());
final List<MatOfPoint2f> patternList = new ArrayList<MatOfPoint2f>();
patternList.add(boardCorners.get());
Optional<Dimension2D> paperDimensions = acm.findPaperPattern(mat,
patternList);
assertTrue(paperDimensions.isPresent());
PerspectiveManager pm = new PerspectiveManager("C270", new BoundingBox(329, 35, 701, 545),
new Dimension2D(1280, 720), paperDimensions.get(), new Dimension2D(1024, 768));
pm.calculateUnknown();
assertEquals(3504, pm.getCameraDistance());
pm.setShooterDistance(pm.getCameraDistance());
Optional<Dimension2D> dims = pm.calculateObjectSize(279, 216, pm.getCameraDistance());
assertTrue(dims.isPresent());
assertEquals(166.00, dims.get().getWidth(), 1);
assertEquals(123.00, dims.get().getHeight(), 1);
pm.setCameraDistance(-1);
pm.calculateUnknown();
assertEquals(3502, pm.getCameraDistance());
pm = new PerspectiveManager(new BoundingBox(329, 35, 701, 545),
new Dimension2D(1280, 720), paperDimensions.get(), new Dimension2D(1024, 768));
pm.setCameraDistance(3504);
pm.calculateUnknown();
assertEquals(3.58, pm.getSensorWidth(), .05);
assertEquals(2.02, pm.getSensorHeight(), .05);
}
@Test
public void testPaperPatternSmall() throws IOException {
BufferedImage testFrame = ImageIO
.read(TestAutoCalibration.class.getResourceAsStream("/perspective/c270_pattern_new_small.png"));
Mat matTemp = Camera.bufferedImageToMat(testFrame);
final Mat mat = new Mat();
Imgproc.cvtColor(matTemp, mat, Imgproc.COLOR_BGR2GRAY);
final Optional<MatOfPoint2f> boardCorners = acm.findChessboard(mat);
assertTrue(boardCorners.isPresent());
final List<MatOfPoint2f> patternList = new ArrayList<MatOfPoint2f>();
patternList.add(boardCorners.get());
Optional<Dimension2D> paperDimensions = acm.findPaperPattern(mat,
patternList);
PerspectiveManager pm = new PerspectiveManager("C270", new BoundingBox(0, 0, 698, 544),
new Dimension2D(1280, 720), paperDimensions.get(), new Dimension2D(1024, 768));
pm.setCameraDistance(6767);
assertEquals(6767, pm.getCameraDistance());
pm.setShooterDistance(pm.getCameraDistance());
Optional<Dimension2D> dims = pm.calculateObjectSize(279, 216, pm.getCameraDistance());
assertTrue(dims.isPresent());
assertEquals(86.2, dims.get().getWidth(), 1);
assertEquals(62.24, dims.get().getHeight(), 1);
pm.setCameraDistance(-1);
pm.calculateUnknown();
assertEquals(6927, pm.getCameraDistance());
}
@Test(expected = IllegalArgumentException.class)
public void testDesiredDistanceCannotBeZero() {
PerspectiveManager pm = new PerspectiveManager("C270", new Dimension2D(1280, 720), new BoundingBox(0, 0, 736, 544));
pm.setCameraFeedSize(1280, 720);
pm.setCameraDistance(3406);
pm.setShooterDistance(3406);
pm.setProjectorResolution(1024, 768);
pm.calculateUnknown();
pm.calculateObjectSize(10, 10, 0);
}
}