Skip to content

Commit

Permalink
Fix several issues, improve parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
nfeybesse committed Jun 5, 2018
1 parent 30efe60 commit 29a9ed8
Show file tree
Hide file tree
Showing 11 changed files with 202 additions and 228 deletions.
Expand Up @@ -6,7 +6,7 @@

interface GSCapture {
public static final Size HD = new Size(1280, 720);
public static final Size VGA = new Size(640, 360);
public static final Size VGA = new Size(320, 180);

SuperFrameImg read();

Expand Down
Expand Up @@ -43,7 +43,7 @@ public SuperFrameImg read() {
boolean result = videoCapture.read(frameMat);
if (!result)
throw new IllegalStateException("Unable to read camera");
Imgproc.resize(frameMat, frameMat, resize, 0, 0, Imgproc.INTER_CUBIC);
Imgproc.resize(frameMat, frameMat, resize, 1, 1, Imgproc.INTER_LINEAR);
return new SuperFrameImg(frameMat, new double[] { frameMat.width() / 2, frameMat.height() / 2 }, f);
}

Expand Down
Expand Up @@ -48,7 +48,7 @@ public double interpolateHorizontals(double x, double y) {
hAngle += hCoef * op.angle;
sumHCoefs += hCoef;
}
return hAngle / sumHCoefs;
return Math.tan(hAngle / sumHCoefs);
}

@Override
Expand All @@ -61,6 +61,6 @@ public double interpolateVerticals(double x, double y) {
vAngle += vCoef * op.angle;
sumVCoefs += vCoef;
}
return vAngle / sumVCoefs;
return -Math.tan(vAngle / sumVCoefs);
}
}
@@ -1,5 +1,18 @@
package org.genericsystem.cv.application;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.apache.commons.math3.analysis.interpolation.LinearInterpolator;
import org.apache.commons.math3.analysis.polynomials.PolynomialSplineFunction;
import org.genericsystem.cv.Img;
Expand All @@ -19,19 +32,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class RadonTransform {

static {
Expand Down
Expand Up @@ -46,7 +46,7 @@ public static void main(String[] args) {
private SuperFrameImg superFrame = gsCapture.read();
private ScheduledExecutorService timer = new BoundedScheduledThreadPoolExecutor();
private Config config = new Config();
private final ImageView[][] imageViews = new ImageView[][] { new ImageView[3], new ImageView[3], new ImageView[3], new ImageView[3], new ImageView[3] };
private final ImageView[][] imageViews = new ImageView[][] { new ImageView[3], new ImageView[3], new ImageView[3], new ImageView[3] };
private int frameCount = 0;

private void startTimer() {
Expand All @@ -69,7 +69,7 @@ private void startTimer() {

@Override
protected void fillGrid(GridPane mainGrid) {
double displaySizeReduction = 1.5;
double displaySizeReduction = 1;
for (int col = 0; col < imageViews.length; col++)
for (int row = 0; row < imageViews[col].length; row++) {
ImageView imageView = new ImageView();
Expand Down Expand Up @@ -104,14 +104,14 @@ private Image[] doWork() {
Img transposedBinarized = binarized.transpose();
ref = trace("Binarization", ref);

double vRecover = 0.8;
int vStripsNumber = 24;
double vRecover = 0.7;
int vStripsNumber = 8;
double stripWidth = (binarized.width() / (vStripsNumber * (1 - vRecover) + vRecover));
double vStep = ((1 - vRecover) * stripWidth);
System.out.println(vStripsNumber + " verticals strips with width : " + stripWidth + " each step : " + vStep);

double hRecover = 0.8;
int hStripsNumber = 12;
double hRecover = 0.7;
int hStripsNumber = 4;
double stripHeight = (binarized.height() / (hStripsNumber * (1 - hRecover) + hRecover));
double hStep = ((1 - hRecover) * stripHeight);
System.out.println(hStripsNumber + " horizontal strips with width : " + stripHeight + " each step : " + hStep);
Expand All @@ -131,22 +131,52 @@ private Image[] doWork() {
List<List<HoughTrajectStep>> hHoughTrajs = hHoughs.stream().map(projectionMap -> RadonTransform.bestTrajectFHT(projectionMap, 11, -0.2)).collect(Collectors.toList());
ref = trace("Compute trajects", ref);

for (int vStripIndex = 0; vStripIndex < vHoughTrajs.size(); vStripIndex++) {
System.out.println(vStripIndex * vStep + stripWidth / 2);
}

List<List<OrientedPoint>[]> fhtHorizontals = new ArrayList<>();
for (int vStripIndex = 0; vStripIndex < vHoughTrajs.size(); vStripIndex++)
fhtHorizontals.add(RadonTransform.toHorizontalOrientedPoints(vHoughTrajs.get(vStripIndex), vStripIndex * vStep + stripWidth / 2, 0.4, 0.03));
List<List<OrientedPoint>[]> fhtVerticals = new ArrayList<>();
for (int hStrip = 0; hStrip < hHoughTrajs.size(); hStrip++)
fhtVerticals.add(RadonTransform.toVerticalOrientedPoints(hHoughTrajs.get(hStrip), hStrip * hStep + stripHeight / 2, 0.4, 0.03));

List<List<Segment>>[] horizontalSegments = connect(fhtHorizontals, hStep, 0.05, false);
List<List<Segment>>[] horizontalSegments = connect(fhtHorizontals, vStep, 0.05, false);
List<List<Segment>>[] verticalSegments = connect(fhtVerticals, hStep, 0.05, true);

Img frameDisplayFHT = new Img(superFrame.getFrame().getSrc().clone(), false);
for (OrientedPoint op : horizontalSegments[0].stream().flatMap(h -> h.stream()).flatMap(edge -> Stream.of(edge.op1, edge.op2)).collect(Collectors.toList())) {
Imgproc.line(frameDisplayFHT.getSrc(), new Point(op.center.x - Math.cos(op.angle) * vStep * op.strenght, op.center.y - Math.sin(op.angle) * hStep * op.strenght),
new Point(op.center.x + Math.cos(op.angle) * vStep * op.strenght, op.center.y + Math.sin(op.angle) * hStep * op.strenght), new Scalar(0, 255, 0), 1);

}
for (OrientedPoint op : horizontalSegments[1].stream().flatMap(h -> h.stream()).flatMap(edge -> Stream.of(edge.op1, edge.op2)).collect(Collectors.toList())) {
Imgproc.line(frameDisplayFHT.getSrc(), new Point(op.center.x - Math.cos(op.angle) * vStep * op.strenght, op.center.y - Math.sin(op.angle) * hStep * op.strenght),
new Point(op.center.x + Math.cos(op.angle) * vStep * op.strenght, op.center.y + Math.sin(op.angle) * hStep * op.strenght), new Scalar(0, 0, 255), 1);

}

for (OrientedPoint op : verticalSegments[0].stream().flatMap(h -> h.stream()).flatMap(edge -> Stream.of(edge.op1, edge.op2)).collect(Collectors.toList())) {
Imgproc.line(frameDisplayFHT.getSrc(), new Point(op.center.x + Math.sin(op.angle) * vStep * op.strenght, op.center.y - Math.cos(op.angle) * hStep * op.strenght),
new Point(op.center.x - Math.sin(op.angle) * vStep * op.strenght, op.center.y + Math.cos(op.angle) * hStep * op.strenght), new Scalar(255, 255, 0), 1);

}
for (OrientedPoint op : verticalSegments[1].stream().flatMap(h -> h.stream()).flatMap(edge -> Stream.of(edge.op1, edge.op2)).collect(Collectors.toList())) {
Imgproc.line(frameDisplayFHT.getSrc(), new Point(op.center.x + Math.sin(op.angle) * vStep * op.strenght, op.center.y - Math.cos(op.angle) * hStep * op.strenght),
new Point(op.center.x - Math.sin(op.angle) * vStep * op.strenght, op.center.y + Math.cos(op.angle) * hStep * op.strenght), new Scalar(255, 0, 255), 1);

}
images[2] = frameDisplayFHT.toJfxImage();
ref = trace("Display lines", ref);

List<PolynomialSplineFunction>[] horizontalSplines = toSplines(horizontalSegments, false);
List<List<Segment>>[] verticalSegments = connect(fhtVerticals, vStep, 0.05, true);
List<PolynomialSplineFunction>[] verticalSplines = toSplines(verticalSegments, true);

List<OrientedPoint> flatHorizontalSegments = Stream.of(horizontalSegments).flatMap(h -> h.stream()).flatMap(h -> h.stream()).flatMap(edge -> Stream.of(edge.op1, edge.op2)).collect(Collectors.toList());
List<OrientedPoint> flatVerticalSegments = Stream.of(verticalSegments).flatMap(h -> h.stream()).flatMap(h -> h.stream()).flatMap(edge -> Stream.of(edge.op1, edge.op2)).collect(Collectors.toList());

GeneralInterpolator interpolatorFHT = new GeneralInterpolator(flatHorizontalSegments, flatVerticalSegments, 4, 0.0001);
SplineInterpolator superInterpolator = new SplineInterpolator(interpolatorFHT, horizontalSplines, verticalSplines);

ref = trace("Prepare interpolator", ref);

Img splineDisplay = new Img(superFrame.getFrame().getSrc().clone(), false);
for (PolynomialSplineFunction spline : horizontalSplines[0])
for (double x = spline.getKnots()[0]; x < spline.getKnots()[spline.getKnots().length - 1]; x++)
Expand All @@ -162,107 +192,51 @@ private Image[] doWork() {
for (double y = spline.getKnots()[0]; y < spline.getKnots()[spline.getKnots().length - 1]; y++)
splineDisplay.getSrc().put((int) y, (int) Math.round(spline.value(y)), 255, 0, 255);

images[2] = splineDisplay.toJfxImage();
images[3] = splineDisplay.toJfxImage();
ref = trace("Display splines", ref);

List<OrientedPoint> flatHorizontalSegments = Stream.of(horizontalSegments).flatMap(h -> h.stream()).flatMap(h -> h.stream()).flatMap(edge -> Stream.of(edge.op1, edge.op2)).collect(Collectors.toList());
List<OrientedPoint> flatVerticalSegments = Stream.of(verticalSegments).flatMap(h -> h.stream()).flatMap(h -> h.stream()).flatMap(edge -> Stream.of(edge.op1, edge.op2)).collect(Collectors.toList());

List<OrientedPoint> flatFhtVerticals = fhtVerticals.stream().flatMap(h -> Stream.of(h)).flatMap(h -> h.stream()).collect(Collectors.toList());
List<OrientedPoint> flatFhtHorizontals = fhtHorizontals.stream().flatMap(h -> Stream.of(h)).flatMap(h -> h.stream()).collect(Collectors.toList());
GeneralInterpolator interpolatorFHT = new GeneralInterpolator(flatHorizontalSegments, flatVerticalSegments, 4, 0.0001);
SplineInterpolator superInterpolator = new SplineInterpolator(interpolatorFHT, horizontalSplines, verticalSplines);

ref = trace("Prepare interpolator", ref);

Img frameDisplayFHT = new Img(superFrame.getFrame().getSrc().clone(), false);

// for (OrientedPoint op : flatFhtVerticals) {
// double angle = op.angle + Math.PI / 2;
// Imgproc.line(frameDisplayFHT.getSrc(), new Point(op.center.x - Math.cos(angle) * stripWidth / 2 * op.strenght, op.center.y - Math.sin(angle) * stripHeight / 2 * op.strenght),
// new Point(op.center.x + Math.cos(angle) * stripWidth / 2 * op.strenght, op.center.y + Math.sin(angle) * stripHeight / 2 * op.strenght), new Scalar(0, 0, 255), 1);
// angle = interpolatorFHT.interpolateVerticals(op.center.x, op.center.y) + Math.PI / 2;
// Imgproc.line(frameDisplayFHT.getSrc(), new Point(op.center.x - Math.cos(angle) * stripWidth / 2 * op.strenght, op.center.y - Math.sin(angle) * stripHeight / 2 * op.strenght),
// new Point(op.center.x + Math.cos(angle) * stripWidth / 2 * op.strenght, op.center.y + Math.sin(angle) * stripHeight / 2 * op.strenght), new Scalar(255, 0, 0), 1);
// }

// for (OrientedPoint op : flatFhtHorizontals) {
// Imgproc.line(frameDisplayFHT.getSrc(), new Point(op.center.x - Math.cos(op.angle) * stripWidth / 2 * op.strenght, op.center.y - Math.sin(op.angle) * stripHeight / 2 * op.strenght),
// new Point(op.center.x + Math.cos(op.angle) * stripWidth / 2 * op.strenght, op.center.y + Math.sin(op.angle) * stripHeight / 2 * op.strenght), new Scalar(0, 0, 255), 1);
// double angle = interpolatorFHT.interpolateHorizontals(op.center.x, op.center.y);
// Imgproc.line(frameDisplayFHT.getSrc(), new Point(op.center.x - Math.cos(angle) * stripWidth / 2 * op.strenght, op.center.y - Math.sin(angle) * stripHeight / 2 * op.strenght),
// new Point(op.center.x + Math.cos(angle) * stripWidth / 2 * op.strenght, op.center.y + Math.sin(angle) * stripHeight / 2 * op.strenght), new Scalar(255, 0, 0), 1);
//
// }

for (OrientedPoint op : horizontalSegments[0].stream().flatMap(h -> h.stream()).flatMap(edge -> Stream.of(edge.op1, edge.op2)).collect(Collectors.toList())) {
Imgproc.line(frameDisplayFHT.getSrc(), new Point(op.center.x - Math.cos(op.angle) * stripWidth / 2 * op.strenght, op.center.y - Math.sin(op.angle) * stripHeight / 2 * op.strenght),
new Point(op.center.x + Math.cos(op.angle) * stripWidth / 2 * op.strenght, op.center.y + Math.sin(op.angle) * stripHeight / 2 * op.strenght), new Scalar(0, 255, 0), 1);

}
for (OrientedPoint op : horizontalSegments[1].stream().flatMap(h -> h.stream()).flatMap(edge -> Stream.of(edge.op1, edge.op2)).collect(Collectors.toList())) {
Imgproc.line(frameDisplayFHT.getSrc(), new Point(op.center.x - Math.cos(op.angle) * stripWidth / 2 * op.strenght, op.center.y - Math.sin(op.angle) * stripHeight / 2 * op.strenght),
new Point(op.center.x + Math.cos(op.angle) * stripWidth / 2 * op.strenght, op.center.y + Math.sin(op.angle) * stripHeight / 2 * op.strenght), new Scalar(0, 0, 255), 1);

}

for (OrientedPoint op : verticalSegments[0].stream().flatMap(h -> h.stream()).flatMap(edge -> Stream.of(edge.op1, edge.op2)).collect(Collectors.toList())) {
Imgproc.line(frameDisplayFHT.getSrc(), new Point(op.center.x + Math.sin(op.angle) * stripWidth / 2 * op.strenght, op.center.y - Math.cos(op.angle) * stripHeight / 2 * op.strenght),
new Point(op.center.x - Math.sin(op.angle) * stripWidth / 2 * op.strenght, op.center.y + Math.cos(op.angle) * stripHeight / 2 * op.strenght), new Scalar(255, 255, 0), 1);

}
for (OrientedPoint op : verticalSegments[1].stream().flatMap(h -> h.stream()).flatMap(edge -> Stream.of(edge.op1, edge.op2)).collect(Collectors.toList())) {
Imgproc.line(frameDisplayFHT.getSrc(), new Point(op.center.x + Math.sin(op.angle) * stripWidth / 2 * op.strenght, op.center.y - Math.cos(op.angle) * stripHeight / 2 * op.strenght),
new Point(op.center.x - Math.sin(op.angle) * stripWidth / 2 * op.strenght, op.center.y + Math.cos(op.angle) * stripHeight / 2 * op.strenght), new Scalar(255, 0, 255), 1);

}
images[3] = frameDisplayFHT.toJfxImage();
ref = trace("Display lines", ref);

MeshManager meshManager = new MeshManager(6, 4, superInterpolator, superFrame.getFrame().getSrc());
ref = trace("Build mesh", ref);

images[4] = new Img(meshManager.drawOnCopy(new Scalar(0, 255, 0), new Scalar(0, 0, 255)), false).toJfxImage();
ref = trace("Draw mesh", ref);
ref = trace("Build and draw mesh", ref);

Img dewarpFHT = new Img(meshManager.dewarp());
images[5] = dewarpFHT.toJfxImage();
ref = trace("Dewarp", ref);
// Img dewarpFHT = new Img(meshManager.dewarp());
// images[5] = dewarpFHT.toJfxImage();
// ref = trace("Dewarp", ref);

Img dewarpedBinarized2 = dewarpFHT.adaptativeGaussianInvThreshold(7, 5);// .canny(20, 80);
images[6] = dewarpedBinarized2.toJfxImage();
ref = trace("Binarize dewarp", ref);
// Img dewarpedBinarized2 = dewarpFHT.adaptativeGaussianInvThreshold(7, 5);// .canny(20, 80);
// images[6] = dewarpedBinarized2.toJfxImage();
// ref = trace("Binarize dewarp", ref);

Layout layout = dewarpedBinarized2.buildLayout(new Size(2, 0.0), new Size(0.001, 0.001), 8);
layout.draw(dewarpFHT, new Scalar(255, 0, 0), new Scalar(0, 0, 255), 1, 2);
images[7] = dewarpFHT.toJfxImage();
ref = trace("Layout", ref);
// Layout layout = dewarpedBinarized2.buildLayout(new Size(2, 0.0), new Size(0.001, 0.001), 8);
// layout.draw(dewarpFHT, new Scalar(255, 0, 0), new Scalar(0, 0, 255), 1, 2);
// images[7] = dewarpFHT.toJfxImage();
// ref = trace("Layout", ref);

images[8] = new Img(meshManager.draw3Dsurface(new Scalar(0, 255, 0), new Scalar(0, 0, 255)), false).toJfxImage();
images[5] = new Img(meshManager.draw3Dsurface(new Scalar(0, 255, 0), new Scalar(0, 0, 255)), false).toJfxImage();
ref = trace("3D surface / svd", ref);

Img dewarpFHT3D = new Img(meshManager.dewarp3D());
images[9] = dewarpFHT3D.toJfxImage();
images[6] = dewarpFHT3D.toJfxImage();
ref = trace("Dewarp 3D", ref);

Img binarized3D = dewarpFHT3D.adaptativeGaussianInvThreshold(7, 5);// .canny(20, 80);
images[10] = binarized3D.toJfxImage();
images[7] = binarized3D.toJfxImage();
ref = trace("Binarize dewarp 3D", ref);

Layout layout3D = binarized3D.buildLayout(new Size(2, 0.0), new Size(0.01, 0.01), 8);
Layout layout3D = binarized3D.buildLayout(new Size(2, 0.0), new Size(0.001, 0.001), 8);
layout3D.draw(dewarpFHT3D, new Scalar(255, 0, 0), new Scalar(0, 0, 255), 1, 2);
images[11] = dewarpFHT3D.toJfxImage();
images[8] = dewarpFHT3D.toJfxImage();
ref = trace("Layout 3D", ref);

meshManager.recomputeGrid();
images[12] = new Img(meshManager.drawOnCopy(new Scalar(0, 255, 0), new Scalar(0, 0, 255)), false).toJfxImage();
ref = trace("Draw mesh", ref);

images[13] = new Img(meshManager.draw3Dsurface(new Scalar(0, 255, 0), new Scalar(0, 0, 255)), false).toJfxImage();
ref = trace("3D surface SVD", ref);

images[14] = new Img(meshManager.dewarp3D(), false).toJfxImage();
ref = trace("Dewarp 3D", ref);
// meshManager.recomputeGrid();
// images[12] = new Img(meshManager.drawOnCopy(new Scalar(0, 255, 0), new Scalar(0, 0, 255)), false).toJfxImage();
// ref = trace("Draw mesh", ref);
//
// images[13] = new Img(meshManager.draw3Dsurface(new Scalar(0, 255, 0), new Scalar(0, 0, 255)), false).toJfxImage();
// ref = trace("3D surface SVD", ref);
//
// images[14] = new Img(meshManager.dewarp3D(), false).toJfxImage();
// ref = trace("Dewarp 3D", ref);

return images;

Expand Down
@@ -1,5 +1,12 @@
package org.genericsystem.cv.application;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.commons.math3.analysis.interpolation.LinearInterpolator;
import org.apache.commons.math3.analysis.polynomials.PolynomialSplineFunction;
import org.genericsystem.cv.AbstractApp;
Expand All @@ -14,13 +21,6 @@
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javafx.application.Platform;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
Expand Down Expand Up @@ -102,7 +102,7 @@ private Image[] doWork() {
int stripWidth = 100;
int w = 50;
Mat vStrip = RadonTransform.extractStrip(binarized.getSrc(), binarized.width() / 2 - stripWidth / 2, stripWidth);
Mat vStrip2 = RadonTransform.extractStrip(binarized.getSrc(), binarized.width() / 2 - stripWidth / 2 + w, stripWidth);
// Mat vStrip2 = RadonTransform.extractStrip(binarized.getSrc(), binarized.width() / 2 - stripWidth / 2 + w, stripWidth);
Mat vStripDisplay = Mat.zeros(binarized.size(), binarized.type());
Mat roi = new Mat(vStripDisplay, new Range(0, binarized.height()), new Range(binarized.width() / 2 - stripWidth / 2, binarized.width() / 2 + stripWidth / 2));
vStrip.copyTo(roi);
Expand Down

0 comments on commit 29a9ed8

Please sign in to comment.