Add linear outline machinery

This commit is contained in:
2026-09-29 10:58:29 +02:00
parent 21faf82da6
commit fd010d8b0c
7 changed files with 182 additions and 24 deletions

View File

@@ -10,9 +10,12 @@ import presenters.MainPresenter;
import presenters.NavPresenter;
import presenters.filtering.local.LocalFilteringPresenter;
import presenters.morphology.BasicMorphologyPresenter;
import presenters.morphology.ComplexMorphologyPresenter;
import presenters.outline.LinearOutlinePresenter;
import services.GlobalFilteringService;
import services.ImageService;
import services.MorphologyService;
import services.OutlineService;
import ui.abstractions.*;
import ui.implementation.components.nav.NavBar;
import ui.implementation.views.DoubleMatrix;
@@ -21,6 +24,7 @@ import ui.implementation.views.MainView;
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;
/**
* Gathers some configurations in order to set the dependency injection container up
@@ -38,6 +42,7 @@ public class AppModule extends AbstractModule {
bind(GlobalFilteringState.class);
bind(BasicMorphologyState.class);
bind(ComplexMorphologyState.class);
bind(LinearOutlineState.class);
//--- Application layer ---
bind(EventBus.class).in(Scopes.SINGLETON);
@@ -51,6 +56,7 @@ public class AppModule extends AbstractModule {
bind(ILocalFilteringView.class).to(LocalFilteringView.class);
bind(IBasicMorphologyView.class).to(BasicMorphologyView.class);
bind(IComplexMorphologyView.class).to(ComplexMorphologyView.class);
bind(ILinearOutlineView.class).to(LinearOutlineView.class);
//--- Presentation layer ---
bind(MainPresenter.class);
@@ -59,13 +65,15 @@ public class AppModule extends AbstractModule {
bind(GlobalFilteringPresenter.class);
bind(LocalFilteringPresenter.class);
bind(BasicMorphologyPresenter.class);
bind(ComplexMorphologyView.class);
bind(ComplexMorphologyPresenter.class);
bind(LinearOutlinePresenter.class);
//--- Service layer layer ---
bind(ImageService.class);
bind(LocalFilteringView.class);
bind(GlobalFilteringService.class);
bind(MorphologyService.class);
bind(OutlineService.class);
}
}

View File

@@ -1,4 +1,66 @@
package app.state;
public class LinearOutlineState extends State{
}
import com.google.inject.Inject;
import domain.image.Image;
import presenters.outline.LinearOutlineListener;
import java.util.ArrayList;
import java.util.List;
public class LinearOutlineState extends State {
private Image prewitt;
private Image sobel;
private Image laplacian4;
private Image laplacian8;
private final List<LinearOutlineListener> listeners = new ArrayList<>();
@Inject
public LinearOutlineState() {
}
public void subscribe(LinearOutlineListener listener) {
listeners.add(listener);
}
public void unsubscribe(LinearOutlineListener listener) {
listeners.remove(listener);
}
public void setPrewitt(Image image) {
prewitt = image;
listeners.forEach(listener -> listener.onPrewittChanged(image));
}
public void setSobel(Image image) {
sobel = image;
listeners.forEach(listener -> listener.onSobelChanged(image));
}
public void setLaplacian4(Image image) {
laplacian4 = image;
listeners.forEach(listener -> listener.onLaplacian4Changed(image));
}
public void setLaplacian8(Image image) {
laplacian8 = image;
listeners.forEach(listener -> listener.onLaplacian8Changed(image));
}
public Image getPrewitt() {
return prewitt;
}
public Image getSobel() {
return sobel;
}
public Image getLaplacian4() {
return laplacian4;
}
public Image getLaplacian8() {
return laplacian8;
}
}

View File

@@ -18,17 +18,17 @@ public class LinearOutline {
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 if (direction == 2) {
kernel.put(0, 0,
-1, 0, 1,
-1, 0, 1,
-1, 0, 1
);
} else {
throw new IllegalArgumentException("Direction must be 1 or 2");
}
@@ -46,17 +46,17 @@ public class LinearOutline {
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 if (direction == 2) {
kernel.put(0, 0,
-1, 0, 1,
-2, 0, 2,
-1, 0, 1
);
} else {
throw new IllegalArgumentException("Direction must be 1 or 2");
}

View File

@@ -1,5 +1,14 @@
package presenters.outline;
import domain.image.Image;
public interface LinearOutlineListener {
}
void onPrewittChanged(Image image);
void onSobelChanged(Image image);
void onLaplacian4Changed(Image image);
void onLaplacian8Changed(Image image);
}

View File

@@ -2,8 +2,10 @@ package presenters.outline;
import app.state.AppState;
import app.state.LinearOutlineState;
import domain.image.Image;
import jakarta.inject.Inject;
import services.OutlineService;
import ui.abstractions.ILinearOutlineView;
public class LinearOutlinePresenter implements LinearOutlineListener {
@@ -11,6 +13,8 @@ public class LinearOutlinePresenter implements LinearOutlineListener {
private final LinearOutlineState outlineState;
private final OutlineService outlineService;
private ILinearOutlineView view;
@Inject
public LinearOutlinePresenter(
AppState appState,
@@ -20,24 +24,76 @@ public class LinearOutlinePresenter implements LinearOutlineListener {
this.appState = appState;
this.outlineState = outlineState;
this.outlineService = outlineService;
outlineState.subscribe(this);
}
public void setView(Object o) {
public void setView(ILinearOutlineView view) {
this.view = view;
}
public void dispose() {
view = null;
outlineState.unsubscribe(this);
}
public void computePrewittGradient(int direction) {
Image image = appState.getImage();
Image result = outlineService.prewittGradient(image, direction);
outlineState.setPrewitt(result);
}
public void computeSobelGradient(int direction) {
Image image = appState.getImage();
Image result = outlineService.sobelGradient(image, direction);
outlineState.setSobel(result);
}
public void computeLaplacian4() {
Image image = appState.getImage();
Image result = outlineService.laplacian4(image);
outlineState.setLaplacian4(result);
}
public void computeLaplacian8() {
Image image = appState.getImage();
Image result = outlineService.laplacian8(image);
outlineState.setLaplacian8(result);
}
}
@Override
public void onPrewittChanged(Image image) {
if (view != null) {
view.updatePrewitt(image);
}
}
@Override
public void onSobelChanged(Image image) {
if (view != null) {
view.updateSobel(image);
}
}
@Override
public void onLaplacian4Changed(Image image) {
if (view != null) {
view.updateLaplacian4(image);
}
}
@Override
public void onLaplacian8Changed(Image image) {
if (view != null) {
view.updateLaplacian8(image);
}
}
}

View File

@@ -1,4 +1,32 @@
package services;
import domain.image.Image;
import domain.image.processing.outline.LinearOutline;
public class OutlineService {
public Image prewittGradient(Image image, int direction) {
return LinearOutline
.prewittGradient(image, direction)
.toImage();
}
public Image sobelGradient(Image image, int direction) {
return LinearOutline
.sobelGradient(image, direction)
.toImage();
}
public Image laplacian4(Image image) {
return LinearOutline
.laplacian4(image)
.toImage();
}
public Image laplacian8(Image image) {
return LinearOutline
.laplacian8(image)
.toImage();
}
}

View File

@@ -36,12 +36,7 @@ public class LinearOutlineView extends AbstractView implements ILinearOutlineVie
modeTab.addPreviewTab(LAPLACIAN4_TAB_TITLE);
modeTab.addPreviewTab(LAPLACIAN8_TAB_TITLE);
directionComboBox = new JComboBox<>(
new String[]{
"Horizontale",
"Verticale"
}
);
directionComboBox = new JComboBox<>( new String[]{ "Horizontale", "Verticale" } );
JButton applyButton = new JButton("Appliquer");
applyButton.addActionListener(e -> applyOutline());