Add some use cases
This commit is contained in:
@@ -10,6 +10,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class UseCasePresenter {
|
||||
|
||||
@@ -38,7 +39,12 @@ public class UseCasePresenter {
|
||||
public void computeNoiseReduction() {
|
||||
Image image1 = loadImage(NOISE_1_IMAGE);
|
||||
Image image2 = loadImage(NOISE_2_IMAGE);
|
||||
Image[] results = {service.reduceNoise(image1), service.reduceNoise(image2)};
|
||||
|
||||
Image reduced1 = measureTime("Reduction 1", () -> service.reduceNoise(image1, 0.5f, 7));
|
||||
Image reduced2 = measureTime("Reduction 2", () -> service.reduceNoise(image2, 1f, 5));
|
||||
|
||||
Image[] results = { reduced1, reduced2 };
|
||||
|
||||
view.updateNoiseReduction(results[0], results[1]);
|
||||
}
|
||||
|
||||
@@ -50,13 +56,13 @@ public class UseCasePresenter {
|
||||
|
||||
public void computePeasSegmentation() {
|
||||
Image image = loadImage(PEAS_IMAGE);
|
||||
Image[] results = service.segmentPeas(image);
|
||||
Image[] results = measureTime("Peas segmentation", () -> service.segmentPeas(image));
|
||||
view.updatePeasSegmentation(results[0], results[1]);
|
||||
}
|
||||
|
||||
public void computeBarnacleSegmentation() {
|
||||
Image image = loadImage(BARNACLES_IMAGE);
|
||||
Image[] results = service.segmentBarnacles(image);
|
||||
Image[] results =measureTime("Barnacle segmentation", () -> service.segmentBarnacles(image));
|
||||
view.updateBarnacleSegmentation(results[0], results[1]);
|
||||
}
|
||||
|
||||
@@ -95,4 +101,16 @@ public class UseCasePresenter {
|
||||
public void dispose() {
|
||||
view = null;
|
||||
}
|
||||
|
||||
public <T> T measureTime(String name, Supplier<T> operation) {
|
||||
long start = System.nanoTime();
|
||||
|
||||
T result = operation.get();
|
||||
|
||||
long elapsed = (System.nanoTime() - start) / 1_000_000;
|
||||
System.out.println(name + " took " + elapsed + " ms");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,23 +2,26 @@ package services;
|
||||
|
||||
import domain.image.GrayScaleMatrix;
|
||||
import domain.image.Image;
|
||||
import domain.image.Pixel;
|
||||
import domain.image.processing.filtering.GlobalLinearFiltering;
|
||||
import domain.image.processing.morphology.BasicMorphology;
|
||||
import domain.image.processing.morphology.ComplexMorphology;
|
||||
import domain.image.processing.threshold.Thresholding;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class UseCaseService {
|
||||
|
||||
public Image reduceNoise(Image i0) {
|
||||
public Image reduceNoise(Image i0, float cutOffPercentage, int maskSize) {
|
||||
|
||||
double cutoff = 0.7 * getMaxCutoff(i0.getWidth(), i0.getHeight());
|
||||
double cutoff = cutOffPercentage * getMaxCutoff(i0.getWidth(), i0.getHeight());
|
||||
|
||||
GrayScaleMatrix m0 = i0.toGrayScale();
|
||||
|
||||
GrayScaleMatrix m1 = measureTime("Butterworth low pass", () -> GlobalLinearFiltering.butterworthLowPassFiltering(m0, cutoff, 1));
|
||||
GrayScaleMatrix m1 = GlobalLinearFiltering.butterworthLowPassFiltering(m0, cutoff, 1);
|
||||
Image i1 = m1.toImage();
|
||||
|
||||
return measureTime("Median filter", () -> ComplexMorphology.medianFilter(i1, 5).toImage());
|
||||
return ComplexMorphology.medianFilter(i1, maskSize).toImage();
|
||||
}
|
||||
|
||||
public Image[] equalizeHistogram(Image image) {
|
||||
@@ -28,15 +31,81 @@ public class UseCaseService {
|
||||
}
|
||||
|
||||
public Image[] segmentPeas(Image image) {
|
||||
Image bluePeas = extractBluePeas(image);
|
||||
Image redPeas = extractRedPeas(image);
|
||||
return new Image[]{bluePeas, redPeas};
|
||||
int width = image.getWidth();
|
||||
int height = image.getHeight();
|
||||
Pixel[][] bluePixels = new Pixel[height][width];
|
||||
Pixel[][] redPixels = new Pixel[height][width];
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
Pixel pixel = image.getPixel(x, y);
|
||||
int red = pixel.getRed();
|
||||
int green = pixel.getGreen();
|
||||
int blue = pixel.getBlue();
|
||||
|
||||
boolean isBlue = blue > red * 1.2 && blue > green * 1.2;
|
||||
boolean isRed = red > blue * 1.2 && red > green * 1.2;
|
||||
|
||||
bluePixels[y][x] = isBlue ? new Pixel(255, 255, 255) : new Pixel(0, 0, 0);
|
||||
redPixels[y][x] = isRed ? new Pixel(255, 255, 255) : new Pixel(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return new Image[]{
|
||||
new Image(bluePixels),
|
||||
new Image(redPixels)
|
||||
};
|
||||
}
|
||||
|
||||
public Image[] segmentBarnacles(Image image) {
|
||||
Image largeBarnacles = extractLargeBarnacles(image);
|
||||
Image smallBarnacles = extractSmallBarnacles(image);
|
||||
return new Image[]{largeBarnacles, smallBarnacles};
|
||||
GrayScaleMatrix base = image.toGrayScale();
|
||||
|
||||
Image largeThreshold = Thresholding.simpleThreshold(image, 128).toImage();
|
||||
Image largeClosing = BasicMorphology.closing(largeThreshold, 7).toImage();
|
||||
Image largeOpening = BasicMorphology.opening(largeClosing, 31).toImage();
|
||||
GrayScaleMatrix largeMask = BasicMorphology.dilation(largeOpening, 11);
|
||||
double[][] baseData = base.getRawData();
|
||||
double[][] largeMaskData = largeMask.getRawData();
|
||||
double[][] largeResult = new double[base.getHeight()][base.getWidth()];
|
||||
|
||||
for (int y = 0; y < base.getHeight(); y++) {
|
||||
for (int x = 0; x < base.getWidth(); x++) {
|
||||
largeResult[y][x] = largeMaskData[y][x] > 0 ? baseData[y][x] : 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Small barnacles
|
||||
GrayScaleMatrix small = Thresholding.simpleThreshold(image, 198);
|
||||
GrayScaleMatrix smallMask = BasicMorphology.closing(small.toImage(), 9);
|
||||
|
||||
double[][] smallMaskData = smallMask.getRawData();
|
||||
|
||||
for (int y = 0; y < base.getHeight(); y++) {
|
||||
for (int x = 0; x < base.getWidth(); x++) {
|
||||
if (largeMaskData[y][x] > 0) {
|
||||
smallMaskData[y][x] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
smallMask = new GrayScaleMatrix(smallMaskData);
|
||||
Image smallMaskImage = smallMask.toImage();
|
||||
Image smallOpening = BasicMorphology.opening(smallMaskImage, 5).toImage();
|
||||
smallMask =BasicMorphology.dilation(smallOpening, 5);
|
||||
|
||||
smallMaskData = smallMask.getRawData();
|
||||
double[][] smallResult = new double[base.getHeight()][base.getWidth()];
|
||||
|
||||
for (int y = 0; y < base.getHeight(); y++) {
|
||||
for (int x = 0; x < base.getWidth(); x++) {
|
||||
smallResult[y][x] = smallMaskData[y][x] > 0 ? baseData[y][x] : 0;
|
||||
}
|
||||
}
|
||||
|
||||
return new Image[]{
|
||||
new GrayScaleMatrix(largeResult).toImage(),
|
||||
new GrayScaleMatrix(smallResult).toImage()
|
||||
};
|
||||
}
|
||||
|
||||
public Image segmentTools(Image image) {
|
||||
@@ -93,17 +162,6 @@ public class UseCaseService {
|
||||
return image;
|
||||
}
|
||||
|
||||
public <T> T measureTime(String name, Supplier<T> operation) {
|
||||
long start = System.nanoTime();
|
||||
|
||||
T result = operation.get();
|
||||
|
||||
long elapsed = (System.nanoTime() - start) / 1_000_000;
|
||||
System.out.println(name + " took " + elapsed + " ms");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private double getMaxCutoff(int width, int height) {
|
||||
return Math.sqrt(Math.pow(width / 2.0, 2) + Math.pow(height / 2.0, 2));
|
||||
}
|
||||
|
||||
@@ -12,39 +12,23 @@ import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class UseCaseView extends AbstractView implements IUseCaseView {
|
||||
|
||||
private static final String NOISE_1_TAB_TITLE = "Bruit 1";
|
||||
private static final String NOISE_2_TAB_TITLE = "Bruit 2";
|
||||
|
||||
private static final String HISTOGRAM_RGB_TAB_TITLE = "Égalisation RGB";
|
||||
private static final String HISTOGRAM_LUMINANCE_TAB_TITLE = "Égalisation luminance";
|
||||
|
||||
private static final String PEAS_BLUE_TAB_TITLE = "Pois bleus";
|
||||
private static final String PEAS_RED_TAB_TITLE = "Pois rouges";
|
||||
|
||||
private static final String BARNACLE_LARGE_TAB_TITLE = "Balanes grandes";
|
||||
private static final String BARNACLE_SMALL_TAB_TITLE = "Balanes petites";
|
||||
|
||||
private static final String TOOLS_TAB_TITLE = "Outils";
|
||||
|
||||
private static final String SPACECRAFT_TAB_TITLE = "Synthèse";
|
||||
private static final String SPACECRAFT_CONTOUR_TAB_TITLE = "Synthèse contour";
|
||||
|
||||
private static final String TOAST_TAB_TITLE = "Tartines";
|
||||
private static final String NOISE_1_TAB_TITLE = "1. Bruit 1";
|
||||
private static final String NOISE_2_TAB_TITLE = "1. Bruit 2";
|
||||
private static final String HISTOGRAM_RGB_TAB_TITLE = "2. Égalisation RGB";
|
||||
private static final String HISTOGRAM_LUMINANCE_TAB_TITLE = "2. Égalisation luminance";
|
||||
private static final String PEAS_BLUE_TAB_TITLE = "3. Pois bleus";
|
||||
private static final String PEAS_RED_TAB_TITLE = "3. Pois rouges";
|
||||
private static final String BARNACLE_LARGE_TAB_TITLE = "4. Balanes grandes";
|
||||
private static final String BARNACLE_SMALL_TAB_TITLE = "4. Balanes petites";
|
||||
private static final String TOOLS_TAB_TITLE = "5. Outils";
|
||||
private static final String SPACECRAFT_TAB_TITLE = "6. Synthèse";
|
||||
private static final String SPACECRAFT_CONTOUR_TAB_TITLE = "6. Synthèse contour";
|
||||
private static final String TOAST_TAB_TITLE = "7. Tartines";
|
||||
|
||||
private final UseCasePresenter presenter;
|
||||
private final TabbedPanelFactory tabbedPanelFactory;
|
||||
|
||||
private TabbedImagePanel resultPanel;
|
||||
|
||||
private JButton noiseButton;
|
||||
private JButton histogramButton;
|
||||
private JButton peasButton;
|
||||
private JButton barnacleButton;
|
||||
private JButton toolsButton;
|
||||
private JButton spacecraftButton;
|
||||
private JButton toastButton;
|
||||
|
||||
@Inject
|
||||
public UseCaseView(UseCasePresenter presenter, TabbedPanelFactory tabbedPanelFactory) {
|
||||
this.presenter = presenter;
|
||||
@@ -68,54 +52,37 @@ public class UseCaseView extends AbstractView implements IUseCaseView {
|
||||
TOAST_TAB_TITLE
|
||||
);
|
||||
|
||||
noiseButton = new JButton("Bruit");
|
||||
histogramButton = new JButton("Histogramme");
|
||||
peasButton = new JButton("Petits pois");
|
||||
barnacleButton = new JButton("Balanes");
|
||||
toolsButton = new JButton("Outils");
|
||||
spacecraftButton = new JButton("Vaisseau");
|
||||
toastButton = new JButton("Tartines");
|
||||
resultPanel.addChangeListener(e -> computeSelectedExercise());
|
||||
|
||||
noiseButton.addActionListener(e -> presenter.computeNoiseReduction());
|
||||
histogramButton.addActionListener(e -> presenter.computeHistogramEqualization());
|
||||
peasButton.addActionListener(e -> presenter.computePeasSegmentation());
|
||||
barnacleButton.addActionListener(e -> presenter.computeBarnacleSegmentation());
|
||||
toolsButton.addActionListener(e -> presenter.computeToolsSegmentation());
|
||||
spacecraftButton.addActionListener(e -> presenter.computeSpacecraftExtraction());
|
||||
toastButton.addActionListener(e -> presenter.computeToastOutline());
|
||||
|
||||
JPanel controlPanel = createControlPanel();
|
||||
|
||||
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
|
||||
JPanel mainPanel = new JPanel(new BorderLayout());
|
||||
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||
|
||||
mainPanel.add(resultPanel, BorderLayout.CENTER);
|
||||
mainPanel.add(controlPanel, BorderLayout.SOUTH);
|
||||
|
||||
setContentPane(mainPanel);
|
||||
|
||||
setTitle("Applications");
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setSize(1200, 800);
|
||||
setLocationRelativeTo(null);
|
||||
}
|
||||
|
||||
private JPanel createControlPanel() {
|
||||
JPanel panel = new JPanel(new GridLayout(1, 7, 5, 5));
|
||||
private void computeSelectedExercise() {
|
||||
int index = resultPanel.getSelectedIndex();
|
||||
|
||||
panel.add(noiseButton);
|
||||
panel.add(histogramButton);
|
||||
panel.add(peasButton);
|
||||
panel.add(barnacleButton);
|
||||
panel.add(toolsButton);
|
||||
panel.add(spacecraftButton);
|
||||
panel.add(toastButton);
|
||||
|
||||
return panel;
|
||||
switch (index) {
|
||||
case 0, 1 -> presenter.computeNoiseReduction();
|
||||
case 2, 3 -> presenter.computeHistogramEqualization();
|
||||
case 4, 5 -> presenter.computePeasSegmentation();
|
||||
case 6, 7 -> presenter.computeBarnacleSegmentation();
|
||||
case 8 -> presenter.computeToolsSegmentation();
|
||||
case 9, 10 -> presenter.computeSpacecraftExtraction();
|
||||
case 11 -> presenter.computeToastOutline();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initValues() {
|
||||
presenter.setView(this);
|
||||
presenter.computeNoiseReduction();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user