Add UI components for outline
This commit is contained in:
@@ -15,4 +15,6 @@ public interface INavigator {
|
||||
void showConvolutionFiltering();
|
||||
void showBasicMorphology();
|
||||
void showComplexMorphology();
|
||||
void showLinearOutline();
|
||||
void showNonLinearOutline();
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import ui.implementation.views.ViewInitializer;
|
||||
import ui.implementation.views.fitering.local.LocalFilteringView;
|
||||
import ui.implementation.views.morphology.BasicMorphologyView;
|
||||
import ui.implementation.views.morphology.ComplexMorphologyView;
|
||||
import ui.implementation.views.outline.LinearOutlineView;
|
||||
|
||||
/**
|
||||
* Concrete implement of the INavigator interface.
|
||||
@@ -25,6 +26,7 @@ public class SwingNavigator implements INavigator {
|
||||
private final Provider<LocalFilteringView> convolutionFilteringProvider;
|
||||
private final Provider<BasicMorphologyView> basicMorphologyProvider;
|
||||
private final Provider<ComplexMorphologyView> complexMorphologyProvider;
|
||||
private Provider<LinearOutlineView> linearOutlineProvider;
|
||||
|
||||
@Inject
|
||||
public SwingNavigator(
|
||||
@@ -33,7 +35,8 @@ public class SwingNavigator implements INavigator {
|
||||
Provider<NonIdealFilteringView> nonIdealFilteringProvider,
|
||||
Provider<LocalFilteringView> convolutionFilterProvider,
|
||||
Provider<BasicMorphologyView> basicMorphologyProvider,
|
||||
Provider<ComplexMorphologyView> complexMorphologyProvider
|
||||
Provider<ComplexMorphologyView> complexMorphologyProvider,
|
||||
Provider<LinearOutlineView> linearOutlineProvider
|
||||
) {
|
||||
this.doubleMatrixProvider = doubleMatrixProvider;
|
||||
this.filteringProvider = filteringProvider;
|
||||
@@ -41,6 +44,7 @@ public class SwingNavigator implements INavigator {
|
||||
this.convolutionFilteringProvider = convolutionFilterProvider;
|
||||
this.basicMorphologyProvider = basicMorphologyProvider;
|
||||
this.complexMorphologyProvider = complexMorphologyProvider;
|
||||
this.linearOutlineProvider = linearOutlineProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,6 +83,16 @@ public class SwingNavigator implements INavigator {
|
||||
runView(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showLinearOutline() {
|
||||
LinearOutlineView view = linearOutlineProvider.get();
|
||||
runView(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showNonLinearOutline() {
|
||||
}
|
||||
|
||||
private void runView(AbstractView view) {
|
||||
ViewInitializer.Initialize(view);
|
||||
view.setVisible(true);
|
||||
|
||||
4
src/main/java/app/state/LinearOutlineState.java
Normal file
4
src/main/java/app/state/LinearOutlineState.java
Normal file
@@ -0,0 +1,4 @@
|
||||
package app.state;
|
||||
|
||||
public class LinearOutlineState extends State{
|
||||
}
|
||||
127
src/main/java/domain/image/processing/outline/LinearOutline.java
Normal file
127
src/main/java/domain/image/processing/outline/LinearOutline.java
Normal file
@@ -0,0 +1,127 @@
|
||||
package domain.image.processing.outline;
|
||||
|
||||
import domain.image.GrayScaleMatrix;
|
||||
import domain.image.Image;
|
||||
import org.opencv.core.CvType;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
public class LinearOutline {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param image
|
||||
* @param direction applied horizontally if 1, applied vertically if 2
|
||||
* @return
|
||||
*/
|
||||
public static GrayScaleMatrix prewittGradient(Image image, int direction) {
|
||||
Mat kernel = new Mat(3, 3, CvType.CV_64F);
|
||||
|
||||
if (direction == 1) {
|
||||
kernel.put(0, 0,
|
||||
-1, 0, 1,
|
||||
-1, 0, 1,
|
||||
-1, 0, 1
|
||||
);
|
||||
} else if (direction == 2) {
|
||||
kernel.put(0, 0,
|
||||
-1, -1, -1,
|
||||
0, 0, 0,
|
||||
1, 1, 1
|
||||
);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Direction must be 1 or 2");
|
||||
}
|
||||
|
||||
return applyKernel(image, kernel);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param image
|
||||
* @param direction applied horizontally if 1, applied vertically if 2
|
||||
* @return
|
||||
*/
|
||||
public static GrayScaleMatrix sobelGradient(Image image, int direction) {
|
||||
Mat kernel = new Mat(3, 3, CvType.CV_64F);
|
||||
|
||||
if (direction == 1) {
|
||||
kernel.put(0, 0,
|
||||
-1, 0, 1,
|
||||
-2, 0, 2,
|
||||
-1, 0, 1
|
||||
);
|
||||
} else if (direction == 2) {
|
||||
kernel.put(0, 0,
|
||||
-1, -2, -1,
|
||||
0, 0, 0,
|
||||
1, 2, 1
|
||||
);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Direction must be 1 or 2");
|
||||
}
|
||||
|
||||
return applyKernel(image, kernel);
|
||||
}
|
||||
|
||||
public static GrayScaleMatrix laplacian4(Image image) {
|
||||
Mat kernel = new Mat(3, 3, CvType.CV_64F);
|
||||
|
||||
kernel.put(0, 0,
|
||||
0, -1, 0,
|
||||
-1, 4, -1,
|
||||
0, -1, 0
|
||||
);
|
||||
|
||||
return applyKernel(image, kernel);
|
||||
}
|
||||
|
||||
public static GrayScaleMatrix laplacian8(Image image) {
|
||||
Mat kernel = new Mat(3, 3, CvType.CV_64F);
|
||||
|
||||
kernel.put(0, 0,
|
||||
-1, -1, -1,
|
||||
-1, 8, -1,
|
||||
-1, -1, -1
|
||||
);
|
||||
|
||||
return applyKernel(image, kernel);
|
||||
}
|
||||
|
||||
private static GrayScaleMatrix applyKernel(Image image, Mat kernel) {
|
||||
GrayScaleMatrix gray = image.toGrayScale();
|
||||
|
||||
Mat input = new Mat(
|
||||
gray.getHeight(),
|
||||
gray.getWidth(),
|
||||
CvType.CV_64F
|
||||
);
|
||||
|
||||
double[][] data = gray.getRawData();
|
||||
|
||||
for (int y = 0; y < gray.getHeight(); y++) {
|
||||
input.put(y, 0, data[y]);
|
||||
}
|
||||
|
||||
Mat result = new Mat();
|
||||
|
||||
Imgproc.filter2D(
|
||||
input,
|
||||
result,
|
||||
CvType.CV_64F,
|
||||
kernel
|
||||
);
|
||||
|
||||
double[][] output = new double[
|
||||
result.rows()
|
||||
][result.cols()];
|
||||
|
||||
for (int y = 0; y < result.rows(); y++) {
|
||||
for (int x = 0; x < result.cols(); x++) {
|
||||
output[y][x] = result.get(y, x)[0];
|
||||
}
|
||||
}
|
||||
|
||||
return new GrayScaleMatrix(output);
|
||||
}
|
||||
}
|
||||
@@ -54,6 +54,10 @@ public class NavPresenter {
|
||||
|
||||
public void goToComplexMorphology(){ navigator.showComplexMorphology(); }
|
||||
|
||||
public void goToLinearOutline(){ navigator.showLinearOutline(); }
|
||||
|
||||
public void goToNonLinearOutline() { navigator.showNonLinearOutline(); }
|
||||
|
||||
public GrayScaleMatrix getImageGrayMatrix() { return appState.getImage().toGrayScale(); }
|
||||
|
||||
public void setMode(Mode mode) { modeService.setMode(mode); }
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package presenters.outline;
|
||||
|
||||
public interface LinearOutlineListener {
|
||||
|
||||
}
|
||||
43
src/main/java/presenters/outline/LinearOutlinePresenter.java
Normal file
43
src/main/java/presenters/outline/LinearOutlinePresenter.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package presenters.outline;
|
||||
|
||||
import app.state.AppState;
|
||||
import app.state.LinearOutlineState;
|
||||
import jakarta.inject.Inject;
|
||||
import services.OutlineService;
|
||||
|
||||
public class LinearOutlinePresenter implements LinearOutlineListener {
|
||||
|
||||
private final AppState appState;
|
||||
private final LinearOutlineState outlineState;
|
||||
private final OutlineService outlineService;
|
||||
|
||||
@Inject
|
||||
public LinearOutlinePresenter(
|
||||
AppState appState,
|
||||
LinearOutlineState outlineState,
|
||||
OutlineService outlineService
|
||||
) {
|
||||
this.appState = appState;
|
||||
this.outlineState = outlineState;
|
||||
this.outlineService = outlineService;
|
||||
}
|
||||
|
||||
public void setView(Object o) {
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
public void computePrewittGradient(int direction) {
|
||||
}
|
||||
|
||||
public void computeSobelGradient(int direction) {
|
||||
|
||||
}
|
||||
|
||||
public void computeLaplacian4() {
|
||||
}
|
||||
|
||||
public void computeLaplacian8() {
|
||||
}
|
||||
}
|
||||
4
src/main/java/services/OutlineService.java
Normal file
4
src/main/java/services/OutlineService.java
Normal file
@@ -0,0 +1,4 @@
|
||||
package services;
|
||||
|
||||
public class OutlineService {
|
||||
}
|
||||
10
src/main/java/ui/abstractions/ILinearOutlineView.java
Normal file
10
src/main/java/ui/abstractions/ILinearOutlineView.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package ui.abstractions;
|
||||
|
||||
import domain.image.Image;
|
||||
|
||||
public interface ILinearOutlineView {
|
||||
void updatePrewitt(Image image);
|
||||
void updateSobel(Image image);
|
||||
void updateLaplacian4(Image image);
|
||||
void updateLaplacian8(Image image);
|
||||
}
|
||||
@@ -35,6 +35,7 @@ public class NavBar extends JMenuBar implements INavBar {
|
||||
private JMenu linearMenu;
|
||||
private JMenu histogramMenu;
|
||||
private JMenu morphologyMenu;
|
||||
private Menu outlineMenu;
|
||||
|
||||
private NavPresenter presenter;
|
||||
|
||||
@@ -97,6 +98,12 @@ public class NavBar extends JMenuBar implements INavBar {
|
||||
new MenuItem("Complexe", this::displayComplexeMorphology)
|
||||
);
|
||||
|
||||
outlineMenu = new Menu("Contours","/cp_51_p1.jpg",
|
||||
new MenuItem("Linéair", this::displayLinearOutline),
|
||||
new MenuItem("Non-linéair", this::displayNonLinearOutline)
|
||||
);
|
||||
|
||||
|
||||
histogramMenu = new Menu("Histogramme","/report_48_hot.jpg",
|
||||
new MenuItem("Afficher", "/report_32_hot.jpg",this::displayHistogram)
|
||||
);
|
||||
@@ -106,12 +113,14 @@ public class NavBar extends JMenuBar implements INavBar {
|
||||
this.add(fourierMenu);
|
||||
this.add(linearMenu);
|
||||
this.add(morphologyMenu);
|
||||
this.add(outlineMenu);
|
||||
this.add(histogramMenu);
|
||||
|
||||
drawingMenu.setEnabled(false);
|
||||
fourierMenu.setEnabled(false);
|
||||
linearMenu.setEnabled(false);
|
||||
morphologyMenu.setEnabled(false);
|
||||
outlineMenu.setEnabled(false);
|
||||
histogramMenu.setEnabled(false);
|
||||
}
|
||||
|
||||
@@ -181,6 +190,7 @@ public class NavBar extends JMenuBar implements INavBar {
|
||||
fourierMenu.setEnabled(true);
|
||||
linearMenu.setEnabled(true);
|
||||
morphologyMenu.setEnabled(true);
|
||||
outlineMenu.setEnabled(true);
|
||||
histogramMenu.setEnabled(true);
|
||||
}
|
||||
|
||||
@@ -190,6 +200,7 @@ public class NavBar extends JMenuBar implements INavBar {
|
||||
fourierMenu.setEnabled(false);
|
||||
linearMenu.setEnabled(false);
|
||||
morphologyMenu.setEnabled(false);
|
||||
outlineMenu.setEnabled(false);
|
||||
histogramMenu.setEnabled(false);
|
||||
}
|
||||
|
||||
@@ -243,6 +254,15 @@ public class NavBar extends JMenuBar implements INavBar {
|
||||
presenter.goToConvolution();
|
||||
}
|
||||
|
||||
private void displayBasicMorphology(ActionEvent actionEvent) { presenter.goToBasicMorphology(); }
|
||||
|
||||
private void displayComplexeMorphology(ActionEvent actionEvent) { presenter.goToComplexMorphology(); }
|
||||
|
||||
private void displayLinearOutline(ActionEvent actionEvent) { presenter.goToLinearOutline(); }
|
||||
|
||||
private void displayNonLinearOutline(ActionEvent actionEvent) { presenter.goToNonLinearOutline();}
|
||||
|
||||
|
||||
private void displayErrorMessage(String title, String message) {
|
||||
JOptionPane.showMessageDialog(
|
||||
this,
|
||||
@@ -252,7 +272,4 @@ public class NavBar extends JMenuBar implements INavBar {
|
||||
);
|
||||
}
|
||||
|
||||
private void displayBasicMorphology(ActionEvent actionEvent) { presenter.goToBasicMorphology(); }
|
||||
|
||||
private void displayComplexeMorphology(ActionEvent actionEvent) { presenter.goToComplexMorphology(); }
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ public class MainView extends JFrame implements IMainView
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
setSize(new Dimension(750, 500));
|
||||
setSize(new Dimension(850, 550));
|
||||
setLocationRelativeTo(null);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
package ui.implementation.views.outline;
|
||||
|
||||
import domain.image.Image;
|
||||
import jakarta.inject.Inject;
|
||||
import presenters.outline.LinearOutlinePresenter;
|
||||
import ui.abstractions.AbstractView;
|
||||
import ui.abstractions.ILinearOutlineView;
|
||||
import ui.implementation.components.controls.SaveButton;
|
||||
import ui.implementation.components.image.TabbedImagePanel;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class LinearOutlineView extends AbstractView implements ILinearOutlineView {
|
||||
|
||||
private static final String PREWITT_TAB_TITLE = "Gradient Prewitt";
|
||||
private static final String SOBEL_TAB_TITLE = "Gradient Sobel";
|
||||
private static final String LAPLACIAN4_TAB_TITLE = "Laplacien 4";
|
||||
private static final String LAPLACIAN8_TAB_TITLE = "Laplacien 8";
|
||||
|
||||
private final LinearOutlinePresenter presenter;
|
||||
|
||||
private TabbedImagePanel modeTab;
|
||||
private JComboBox<String> directionComboBox;
|
||||
|
||||
@Inject
|
||||
public LinearOutlineView(LinearOutlinePresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initComponents() {
|
||||
modeTab = new TabbedImagePanel();
|
||||
|
||||
modeTab.addPreviewTab(PREWITT_TAB_TITLE);
|
||||
modeTab.addPreviewTab(SOBEL_TAB_TITLE);
|
||||
modeTab.addPreviewTab(LAPLACIAN4_TAB_TITLE);
|
||||
modeTab.addPreviewTab(LAPLACIAN8_TAB_TITLE);
|
||||
|
||||
directionComboBox = new JComboBox<>(
|
||||
new String[]{
|
||||
"Horizontale",
|
||||
"Verticale"
|
||||
}
|
||||
);
|
||||
|
||||
JButton applyButton = new JButton("Appliquer");
|
||||
applyButton.addActionListener(e -> applyOutline());
|
||||
|
||||
JButton saveButton = new SaveButton();
|
||||
|
||||
JPanel controlPanel = createControlPanel(applyButton);
|
||||
|
||||
JPanel rightPanel = new JPanel();
|
||||
|
||||
GroupLayout rightLayout = new GroupLayout(rightPanel);
|
||||
rightPanel.setLayout(rightLayout);
|
||||
rightLayout.setAutoCreateGaps(true);
|
||||
rightLayout.setAutoCreateContainerGaps(true);
|
||||
|
||||
rightLayout.setHorizontalGroup(
|
||||
rightLayout.createParallelGroup(GroupLayout.Alignment.CENTER)
|
||||
.addComponent(controlPanel)
|
||||
.addComponent(saveButton)
|
||||
);
|
||||
|
||||
rightLayout.setVerticalGroup(
|
||||
rightLayout.createSequentialGroup()
|
||||
.addComponent(controlPanel)
|
||||
.addComponent(saveButton)
|
||||
);
|
||||
|
||||
JPanel mainPanel = new JPanel();
|
||||
|
||||
GroupLayout mainLayout = new GroupLayout(mainPanel);
|
||||
mainPanel.setLayout(mainLayout);
|
||||
mainLayout.setAutoCreateGaps(true);
|
||||
mainLayout.setAutoCreateContainerGaps(true);
|
||||
|
||||
mainLayout.setHorizontalGroup(
|
||||
mainLayout.createSequentialGroup()
|
||||
.addComponent(modeTab)
|
||||
.addComponent(rightPanel)
|
||||
);
|
||||
|
||||
mainLayout.setVerticalGroup(
|
||||
mainLayout.createParallelGroup(GroupLayout.Alignment.CENTER)
|
||||
.addComponent(modeTab)
|
||||
.addComponent(rightPanel)
|
||||
);
|
||||
|
||||
setContentPane(mainPanel);
|
||||
|
||||
setTitle("Contours linéaires");
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
pack();
|
||||
}
|
||||
|
||||
private JPanel createControlPanel(JButton applyButton) {
|
||||
JPanel panel = new JPanel();
|
||||
|
||||
GroupLayout layout = new GroupLayout(panel);
|
||||
panel.setLayout(layout);
|
||||
layout.setAutoCreateGaps(true);
|
||||
layout.setAutoCreateContainerGaps(true);
|
||||
|
||||
JLabel directionLabel = new JLabel("Direction :");
|
||||
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(GroupLayout.Alignment.CENTER)
|
||||
.addComponent(directionLabel)
|
||||
.addComponent(
|
||||
directionComboBox,
|
||||
GroupLayout.PREFERRED_SIZE,
|
||||
120,
|
||||
GroupLayout.PREFERRED_SIZE
|
||||
)
|
||||
.addComponent(applyButton)
|
||||
);
|
||||
|
||||
layout.setVerticalGroup(
|
||||
layout.createSequentialGroup()
|
||||
.addComponent(directionLabel)
|
||||
.addComponent(
|
||||
directionComboBox,
|
||||
GroupLayout.PREFERRED_SIZE,
|
||||
GroupLayout.DEFAULT_SIZE,
|
||||
GroupLayout.PREFERRED_SIZE
|
||||
)
|
||||
.addComponent(applyButton)
|
||||
);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initValues() {
|
||||
modeTab.addChangeListener(e -> updateControls());
|
||||
|
||||
presenter.setView(this);
|
||||
|
||||
updateControls();
|
||||
applyOutline();
|
||||
}
|
||||
|
||||
private void updateControls() {
|
||||
boolean hasDirection =
|
||||
modeTab.getSelectedIndex() == 0
|
||||
|| modeTab.getSelectedIndex() == 1;
|
||||
|
||||
directionComboBox.setEnabled(hasDirection);
|
||||
}
|
||||
|
||||
private void applyOutline() {
|
||||
int operation = modeTab.getSelectedIndex();
|
||||
int direction = directionComboBox.getSelectedIndex() + 1;
|
||||
|
||||
switch (operation) {
|
||||
case 0 -> presenter.computePrewittGradient(direction);
|
||||
case 1 -> presenter.computeSobelGradient(direction);
|
||||
case 2 -> presenter.computeLaplacian4();
|
||||
case 3 -> presenter.computeLaplacian8();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePrewitt(Image image) {
|
||||
modeTab.loadImage(PREWITT_TAB_TITLE, image);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSobel(Image image) {
|
||||
modeTab.loadImage(SOBEL_TAB_TITLE, image);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLaplacian4(Image image) {
|
||||
modeTab.loadImage(LAPLACIAN4_TAB_TITLE, image);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLaplacian8(Image image) {
|
||||
modeTab.loadImage(LAPLACIAN8_TAB_TITLE, image);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeCore() {
|
||||
presenter.setView(null);
|
||||
presenter.dispose();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user