I am working on a project aiming to reproduce images using only a fixed number of convex hull / polygons.
I am using JavaFX to have a nice GUI.
A solution to the problem is a list of polygons drawn on a canvas, letting us obtain an image.
To evaluate the quality of the solution, I am taking the image to reproduce and the image obtained from the list of polygons and I calculate the distance between the color of each pixels.
If I have a null distance between the colors of each pixels, I can say that I reproduced the goal image.
The impletation I made of this function is really slow.
To summarize, I search, for each pixels what are the polygons that contains it and then I add their color in the correct order (I am using transparent color so order is important). I calculate the distance between this color and the color I try to reach (on the goal image). I sum up these distances and that's it !
private void computeEval() {
PixelReader pixelReaderSolution = image.getPixelReader();
AtomicReference<Double> eval2 = new AtomicReference<>((double) 0);
Lock lock = new ReentrantLock();
IntStream.range(0, (int) image.getWidth()).parallel()
.forEach(x -> IntStream.range(0, (int) image.getHeight()).parallel()
.forEach(y -> {
Color colorSolution = pixelReaderSolution.getColor(x, y);
Point2D pixel = new Point2D(x, y);
AtomicReference<Color> pixelColor = new AtomicReference<>();
pixelColor.set(null);
polygons.stream()
.filter(convexPolygon -> convexPolygon.getAsPolygon().contains(pixel))
.forEach(convexPolygon -> {
if (pixelColor.get() == null) {
pixelColor.set(convexPolygon.color);
} else {
pixelColor.set(addColor(pixelColor.get(), convexPolygon.color));
}
});
if (pixelColor.get() == null) {
pixelColor.set(Color.WHITE);
}
lock.lock();
eval2.updateAndGet(v -> v + distanceColor(colorSolution, pixelColor.get()));
lock.unlock();
}));
evaluation = 1 - (eval2.get() / (3 * image.getWidth() * image.getHeight()));
}
In the past, I was using the function snapshot which was fast but that forced me to compute the evaluation inside a JavaFX thread; therefore, blocking my entire GUI by putting to much computations in GUI threads.
This current solution allows me to put the computations inside a Service but it is really slow.
I am a bit stuck on this and I am wondering if anyone could have an idea for me...
I may also be using JavaFX in a wrong way.
I can give more of the code, if people are wondering what's the different function around but I'm 100% that it is this function that slow down everything.