Fix complex morphology
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
package app;
|
package app;
|
||||||
|
|
||||||
import app.state.AppState;
|
import app.state.*;
|
||||||
import app.state.DoubleMatrixState;
|
|
||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Scopes;
|
import com.google.inject.Scopes;
|
||||||
@@ -10,13 +9,18 @@ import presenters.filtering.global.GlobalFilteringPresenter;
|
|||||||
import presenters.MainPresenter;
|
import presenters.MainPresenter;
|
||||||
import presenters.NavPresenter;
|
import presenters.NavPresenter;
|
||||||
import presenters.filtering.local.LocalFilteringPresenter;
|
import presenters.filtering.local.LocalFilteringPresenter;
|
||||||
|
import presenters.morphology.BasicMorphologyPresenter;
|
||||||
|
import services.GlobalFilteringService;
|
||||||
import services.ImageService;
|
import services.ImageService;
|
||||||
|
import services.MorphologyService;
|
||||||
import ui.abstractions.*;
|
import ui.abstractions.*;
|
||||||
import ui.implementation.components.nav.NavBar;
|
import ui.implementation.components.nav.NavBar;
|
||||||
import ui.implementation.views.DoubleMatrix;
|
import ui.implementation.views.DoubleMatrix;
|
||||||
import ui.implementation.views.fitering.global.IdealFilteringView;
|
import ui.implementation.views.fitering.global.IdealFilteringView;
|
||||||
import ui.implementation.views.MainView;
|
import ui.implementation.views.MainView;
|
||||||
import ui.implementation.views.fitering.local.LocalFilteringView;
|
import ui.implementation.views.fitering.local.LocalFilteringView;
|
||||||
|
import ui.implementation.views.morphology.BasicMorphologyView;
|
||||||
|
import ui.implementation.views.morphology.ComplexMorphologyView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gathers some configurations in order to set the dependency injection container up
|
* Gathers some configurations in order to set the dependency injection container up
|
||||||
@@ -30,6 +34,10 @@ public class AppModule extends AbstractModule {
|
|||||||
//--- States ---
|
//--- States ---
|
||||||
bind(AppState.class).in(Scopes.SINGLETON);
|
bind(AppState.class).in(Scopes.SINGLETON);
|
||||||
bind(DoubleMatrixState.class);
|
bind(DoubleMatrixState.class);
|
||||||
|
bind(LocalFilteringState.class);
|
||||||
|
bind(GlobalFilteringState.class);
|
||||||
|
bind(BasicMorphologyState.class);
|
||||||
|
bind(ComplexMorphologyState.class);
|
||||||
|
|
||||||
//--- Application layer ---
|
//--- Application layer ---
|
||||||
bind(EventBus.class).in(Scopes.SINGLETON);
|
bind(EventBus.class).in(Scopes.SINGLETON);
|
||||||
@@ -41,6 +49,8 @@ public class AppModule extends AbstractModule {
|
|||||||
bind(IDoubleMatrix.class).to(DoubleMatrix.class);
|
bind(IDoubleMatrix.class).to(DoubleMatrix.class);
|
||||||
bind(IGlobalFilteringView.class).to(IdealFilteringView.class);
|
bind(IGlobalFilteringView.class).to(IdealFilteringView.class);
|
||||||
bind(ILocalFilteringView.class).to(LocalFilteringView.class);
|
bind(ILocalFilteringView.class).to(LocalFilteringView.class);
|
||||||
|
bind(IBasicMorphologyView.class).to(BasicMorphologyView.class);
|
||||||
|
bind(IComplexMorphologyView.class).to(ComplexMorphologyView.class);
|
||||||
|
|
||||||
//--- Presentation layer ---
|
//--- Presentation layer ---
|
||||||
bind(MainPresenter.class);
|
bind(MainPresenter.class);
|
||||||
@@ -48,9 +58,14 @@ public class AppModule extends AbstractModule {
|
|||||||
bind(DoubleMatrixPresenter.class);
|
bind(DoubleMatrixPresenter.class);
|
||||||
bind(GlobalFilteringPresenter.class);
|
bind(GlobalFilteringPresenter.class);
|
||||||
bind(LocalFilteringPresenter.class);
|
bind(LocalFilteringPresenter.class);
|
||||||
|
bind(BasicMorphologyPresenter.class);
|
||||||
|
bind(ComplexMorphologyView.class);
|
||||||
|
|
||||||
//--- Service layer layer ---
|
//--- Service layer layer ---
|
||||||
bind(ImageService.class);
|
bind(ImageService.class);
|
||||||
|
bind(LocalFilteringView.class);
|
||||||
|
bind(GlobalFilteringService.class);
|
||||||
|
bind(MorphologyService.class);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,4 +14,5 @@ public interface INavigator {
|
|||||||
void showButterworth();
|
void showButterworth();
|
||||||
void showConvolutionFiltering();
|
void showConvolutionFiltering();
|
||||||
void showBasicMorphology();
|
void showBasicMorphology();
|
||||||
|
void showComplexMorphology();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package app;
|
|||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
|
import domain.image.processing.complex.ComplexMatrix;
|
||||||
import ui.abstractions.AbstractView;
|
import ui.abstractions.AbstractView;
|
||||||
import ui.implementation.views.DoubleMatrix;
|
import ui.implementation.views.DoubleMatrix;
|
||||||
import ui.implementation.views.fitering.global.IdealFilteringView;
|
import ui.implementation.views.fitering.global.IdealFilteringView;
|
||||||
@@ -9,6 +10,7 @@ import ui.implementation.views.fitering.global.NonIdealFilteringView;
|
|||||||
import ui.implementation.views.ViewInitializer;
|
import ui.implementation.views.ViewInitializer;
|
||||||
import ui.implementation.views.fitering.local.LocalFilteringView;
|
import ui.implementation.views.fitering.local.LocalFilteringView;
|
||||||
import ui.implementation.views.morphology.BasicMorphologyView;
|
import ui.implementation.views.morphology.BasicMorphologyView;
|
||||||
|
import ui.implementation.views.morphology.ComplexMorphologyView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Concrete implement of the INavigator interface.
|
* Concrete implement of the INavigator interface.
|
||||||
@@ -22,6 +24,7 @@ public class SwingNavigator implements INavigator {
|
|||||||
private final Provider<NonIdealFilteringView> nonIdealFilteringProvider;
|
private final Provider<NonIdealFilteringView> nonIdealFilteringProvider;
|
||||||
private final Provider<LocalFilteringView> convolutionFilteringProvider;
|
private final Provider<LocalFilteringView> convolutionFilteringProvider;
|
||||||
private final Provider<BasicMorphologyView> basicMorphologyProvider;
|
private final Provider<BasicMorphologyView> basicMorphologyProvider;
|
||||||
|
private final Provider<ComplexMorphologyView> complexMorphologyProvider;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public SwingNavigator(
|
public SwingNavigator(
|
||||||
@@ -29,13 +32,15 @@ public class SwingNavigator implements INavigator {
|
|||||||
Provider<IdealFilteringView> filteringProvider,
|
Provider<IdealFilteringView> filteringProvider,
|
||||||
Provider<NonIdealFilteringView> nonIdealFilteringProvider,
|
Provider<NonIdealFilteringView> nonIdealFilteringProvider,
|
||||||
Provider<LocalFilteringView> convolutionFilterProvider,
|
Provider<LocalFilteringView> convolutionFilterProvider,
|
||||||
Provider<BasicMorphologyView> basicMorphologyProvider
|
Provider<BasicMorphologyView> basicMorphologyProvider,
|
||||||
|
Provider<ComplexMorphologyView> complexMorphologyProvider
|
||||||
) {
|
) {
|
||||||
this.doubleMatrixProvider = doubleMatrixProvider;
|
this.doubleMatrixProvider = doubleMatrixProvider;
|
||||||
this.filteringProvider = filteringProvider;
|
this.filteringProvider = filteringProvider;
|
||||||
this.nonIdealFilteringProvider = nonIdealFilteringProvider;
|
this.nonIdealFilteringProvider = nonIdealFilteringProvider;
|
||||||
this.convolutionFilteringProvider = convolutionFilterProvider;
|
this.convolutionFilteringProvider = convolutionFilterProvider;
|
||||||
this.basicMorphologyProvider = basicMorphologyProvider;
|
this.basicMorphologyProvider = basicMorphologyProvider;
|
||||||
|
this.complexMorphologyProvider = complexMorphologyProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -68,6 +73,12 @@ public class SwingNavigator implements INavigator {
|
|||||||
runView(view);
|
runView(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showComplexMorphology() {
|
||||||
|
ComplexMorphologyView view = complexMorphologyProvider.get();
|
||||||
|
runView(view);
|
||||||
|
}
|
||||||
|
|
||||||
private void runView(AbstractView view) {
|
private void runView(AbstractView view) {
|
||||||
ViewInitializer.Initialize(view);
|
ViewInitializer.Initialize(view);
|
||||||
view.setVisible(true);
|
view.setVisible(true);
|
||||||
|
|||||||
@@ -2,28 +2,28 @@ package app.state;
|
|||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import domain.image.Image;
|
import domain.image.Image;
|
||||||
import presenters.morphology.MorphologyListener;
|
import presenters.morphology.BasicMorphologyListener;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class MorphologyState extends State {
|
public class BasicMorphologyState extends State {
|
||||||
|
|
||||||
private Image erosion;
|
private Image erosion;
|
||||||
private Image dilation;
|
private Image dilation;
|
||||||
private Image opening;
|
private Image opening;
|
||||||
private Image closing;
|
private Image closing;
|
||||||
|
|
||||||
private final List<MorphologyListener> listeners = new ArrayList<>();
|
private final List<BasicMorphologyListener> listeners = new ArrayList<>();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public MorphologyState() {}
|
public BasicMorphologyState() {}
|
||||||
|
|
||||||
public void subscribe(MorphologyListener listener) {
|
public void subscribe(BasicMorphologyListener listener) {
|
||||||
listeners.add(listener);
|
listeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unsubscribe(MorphologyListener listener) {
|
public void unsubscribe(BasicMorphologyListener listener) {
|
||||||
listeners.remove(listener);
|
listeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
64
src/main/java/app/state/ComplexMorphologyState.java
Normal file
64
src/main/java/app/state/ComplexMorphologyState.java
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package app.state;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import domain.image.Image;
|
||||||
|
import presenters.morphology.ComplexMorphologyListener;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ComplexMorphologyState extends State {
|
||||||
|
|
||||||
|
private Image mask;
|
||||||
|
private Image dilation;
|
||||||
|
private Image reconstruction;
|
||||||
|
private Image mean;
|
||||||
|
|
||||||
|
private final List<ComplexMorphologyListener> listeners = new ArrayList<>();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ComplexMorphologyState() {}
|
||||||
|
|
||||||
|
public void subscribe(ComplexMorphologyListener listener) {
|
||||||
|
listeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unsubscribe(ComplexMorphologyListener listener) {
|
||||||
|
listeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMask(Image mask) {
|
||||||
|
this.mask = mask;
|
||||||
|
listeners.forEach(listeners -> listeners.onMaskChanged(mask));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDilation(Image image) {
|
||||||
|
dilation = image;
|
||||||
|
listeners.forEach(listener -> listener.onGeodesicDilationChanged(image));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReconstruction(Image image) {
|
||||||
|
reconstruction = image;
|
||||||
|
listeners.forEach(listener -> listener.onGeodesicReconstructionChanged(image));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMedian(Image image) {
|
||||||
|
mean = image;
|
||||||
|
listeners.forEach(listener -> listener.onMedianChanged(image));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Image getMask() { return mask; }
|
||||||
|
|
||||||
|
public Image getDilation() {
|
||||||
|
return dilation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Image getReconstruction() {
|
||||||
|
return reconstruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Image getMean() {
|
||||||
|
return mean;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -10,26 +10,30 @@ import org.opencv.imgproc.Imgproc;
|
|||||||
|
|
||||||
public class ComplexMorphology {
|
public class ComplexMorphology {
|
||||||
|
|
||||||
public static GrayScaleMatrix geodesicDilation(Image image, Image mask, int size) {
|
public static GrayScaleMatrix geodesicDilation(Image image, Image mask, int nbIter) {
|
||||||
Mat input = toMat(image);
|
|
||||||
Mat maskMat = toMat(mask);
|
Mat maskMat = toMat(mask);
|
||||||
Mat kernel = createKernel(size);
|
Mat current = toMat(image);
|
||||||
|
Mat kernel = createKernel(3);
|
||||||
|
|
||||||
|
for (int i = 0; i < nbIter; i++) {
|
||||||
Mat dilated = new Mat();
|
Mat dilated = new Mat();
|
||||||
Imgproc.dilate(input, dilated, kernel);
|
|
||||||
|
Imgproc.dilate(current, dilated, kernel);
|
||||||
|
|
||||||
Mat result = new Mat();
|
Mat result = new Mat();
|
||||||
|
|
||||||
Core.min(dilated, maskMat, result);
|
Core.min(dilated, maskMat, result);
|
||||||
|
|
||||||
return toGrayScaleMatrix(result);
|
current = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GrayScaleMatrix geodesicReconstruction(Image marker, Image mask, int size) {
|
return toGrayScaleMatrix(current);
|
||||||
Mat markerMat = toMat(marker);
|
}
|
||||||
Mat maskMat = toMat(mask);
|
|
||||||
Mat kernel = createKernel(size);
|
|
||||||
|
|
||||||
Mat current = markerMat.clone();
|
public static GrayScaleMatrix geodesicReconstruction(Image image, Image mask) {
|
||||||
|
Mat maskMat = toMat(mask);
|
||||||
|
Mat current = toMat(image);
|
||||||
|
Mat kernel = createKernel(3);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
Mat dilated = new Mat();
|
Mat dilated = new Mat();
|
||||||
@@ -38,7 +42,9 @@ public class ComplexMorphology {
|
|||||||
Mat next = new Mat();
|
Mat next = new Mat();
|
||||||
Core.min(dilated, maskMat, next);
|
Core.min(dilated, maskMat, next);
|
||||||
|
|
||||||
if (Core.norm(next, current, Core.NORM_INF) == 0) {
|
double difference = Core.norm(next, current, Core.NORM_INF);
|
||||||
|
|
||||||
|
if (difference == 0) {
|
||||||
return toGrayScaleMatrix(next);
|
return toGrayScaleMatrix(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,11 +52,11 @@ public class ComplexMorphology {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GrayScaleMatrix meanFilter(Image image, int size) {
|
public static GrayScaleMatrix medianFilter(Image image, int tailleMasque) {
|
||||||
Mat input = toMat(image);
|
Mat input = toMat(image);
|
||||||
Mat result = new Mat();
|
Mat result = new Mat();
|
||||||
|
|
||||||
Imgproc.blur(input, result, new Size(size, size));
|
Imgproc.medianBlur(input, result, tailleMasque);
|
||||||
|
|
||||||
return toGrayScaleMatrix(result);
|
return toGrayScaleMatrix(result);
|
||||||
}
|
}
|
||||||
@@ -73,10 +79,7 @@ public class ComplexMorphology {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Mat createKernel(int size) {
|
private static Mat createKernel(int size) {
|
||||||
return Imgproc.getStructuringElement(
|
return Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(size, size));
|
||||||
Imgproc.MORPH_RECT,
|
|
||||||
new Size(size, size)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GrayScaleMatrix toGrayScaleMatrix(Mat mat) {
|
private static GrayScaleMatrix toGrayScaleMatrix(Mat mat) {
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ public class NavPresenter {
|
|||||||
|
|
||||||
public void goToBasicMorphology(){ navigator.showBasicMorphology(); }
|
public void goToBasicMorphology(){ navigator.showBasicMorphology(); }
|
||||||
|
|
||||||
|
public void goToComplexMorphology(){ navigator.showComplexMorphology(); }
|
||||||
|
|
||||||
public GrayScaleMatrix getImageGrayMatrix() { return appState.getImage().toGrayScale(); }
|
public GrayScaleMatrix getImageGrayMatrix() { return appState.getImage().toGrayScale(); }
|
||||||
|
|
||||||
public void setMode(Mode mode) { modeService.setMode(mode); }
|
public void setMode(Mode mode) { modeService.setMode(mode); }
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package presenters.morphology;
|
|||||||
|
|
||||||
import domain.image.Image;
|
import domain.image.Image;
|
||||||
|
|
||||||
public interface MorphologyListener {
|
public interface BasicMorphologyListener {
|
||||||
void onErosionChanged(Image image);
|
void onErosionChanged(Image image);
|
||||||
|
|
||||||
void onDilationChanged(Image image);
|
void onDilationChanged(Image image);
|
||||||
@@ -10,4 +10,6 @@ public interface MorphologyListener {
|
|||||||
void onOpeningChanged(Image image);
|
void onOpeningChanged(Image image);
|
||||||
|
|
||||||
void onClosingChanged(Image image);
|
void onClosingChanged(Image image);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,23 +1,23 @@
|
|||||||
package presenters.morphology;
|
package presenters.morphology;
|
||||||
|
|
||||||
import app.state.AppState;
|
import app.state.AppState;
|
||||||
import app.state.MorphologyState;
|
import app.state.BasicMorphologyState;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import domain.image.Image;
|
import domain.image.Image;
|
||||||
import services.MorphologyService;
|
import services.MorphologyService;
|
||||||
import ui.abstractions.IBasicMorphologyView;
|
import ui.abstractions.IBasicMorphologyView;
|
||||||
|
|
||||||
public class MorphologyPresenter implements MorphologyListener {
|
public class BasicMorphologyPresenter implements BasicMorphologyListener {
|
||||||
|
|
||||||
private final AppState appState;
|
private final AppState appState;
|
||||||
private final MorphologyState morphologyState;
|
private final BasicMorphologyState morphologyState;
|
||||||
private final MorphologyService morphologyService;
|
private final MorphologyService morphologyService;
|
||||||
private IBasicMorphologyView view;
|
private IBasicMorphologyView view;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public MorphologyPresenter(
|
public BasicMorphologyPresenter(
|
||||||
AppState appState,
|
AppState appState,
|
||||||
MorphologyState morphologyState,
|
BasicMorphologyState morphologyState,
|
||||||
MorphologyService morphologyService
|
MorphologyService morphologyService
|
||||||
) {
|
) {
|
||||||
this.appState = appState;
|
this.appState = appState;
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package presenters.morphology;
|
||||||
|
|
||||||
|
import domain.image.Image;
|
||||||
|
|
||||||
|
public interface ComplexMorphologyListener {
|
||||||
|
void onMaskChanged(Image mask);
|
||||||
|
void onGeodesicDilationChanged(Image image);
|
||||||
|
void onGeodesicReconstructionChanged(Image image);
|
||||||
|
void onMedianChanged(Image image);
|
||||||
|
}
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
package presenters.morphology;
|
||||||
|
|
||||||
|
import app.state.AppState;
|
||||||
|
import app.state.ComplexMorphologyState;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import domain.image.Image;
|
||||||
|
import services.MorphologyService;
|
||||||
|
import ui.abstractions.IComplexMorphologyView;
|
||||||
|
|
||||||
|
public class ComplexMorphologyPresenter implements ComplexMorphologyListener {
|
||||||
|
|
||||||
|
private final AppState appState;
|
||||||
|
private final ComplexMorphologyState morphologyState;
|
||||||
|
private final MorphologyService morphologyService;
|
||||||
|
|
||||||
|
private IComplexMorphologyView view;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ComplexMorphologyPresenter(
|
||||||
|
AppState appState,
|
||||||
|
ComplexMorphologyState morphologyState,
|
||||||
|
MorphologyService morphologyService
|
||||||
|
) {
|
||||||
|
this.appState = appState;
|
||||||
|
this.morphologyState = morphologyState;
|
||||||
|
this.morphologyService = morphologyService;
|
||||||
|
|
||||||
|
morphologyState.subscribe(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setView(IComplexMorphologyView view) {
|
||||||
|
this.view = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMask(Image mask) {
|
||||||
|
this.morphologyState.setMask(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void computeGeodesicDilation(int iterations) {
|
||||||
|
Image image = appState.getImage();
|
||||||
|
Image mask = morphologyState.getMask();
|
||||||
|
|
||||||
|
Image result = morphologyService.geodesicDilation(image, mask, iterations);
|
||||||
|
|
||||||
|
morphologyState.setDilation(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void computeGeodesicReconstruction() {
|
||||||
|
Image image = appState.getImage();
|
||||||
|
Image mask = morphologyState.getMask();
|
||||||
|
|
||||||
|
Image result = morphologyService.geodesicReconstruction(image, mask);
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println("IMAGE: "
|
||||||
|
+ image.getWidth() + "x" + image.getHeight());
|
||||||
|
|
||||||
|
System.out.println("MASK: "
|
||||||
|
+ mask.getWidth() + "x" + mask.getHeight());
|
||||||
|
|
||||||
|
System.out.println(
|
||||||
|
"Same object? " + (image == mask)
|
||||||
|
);
|
||||||
|
|
||||||
|
System.out.println("Image : " + image.getPixel(0, 0).grayValue());
|
||||||
|
|
||||||
|
System.out.println("Mask : " + mask.getPixel(0, 0).grayValue());
|
||||||
|
System.out.println("Result : " + result.getPixel(0, 0).grayValue());
|
||||||
|
|
||||||
|
double[][] imageData = image.toGrayScale().getRawData();
|
||||||
|
double[][] maskData = mask.toGrayScale().getRawData();
|
||||||
|
|
||||||
|
int violations = 0;
|
||||||
|
|
||||||
|
for (int y = 0; y < image.getHeight(); y++) {
|
||||||
|
for (int x = 0; x < image.getWidth(); x++) {
|
||||||
|
if (imageData[y][x] > maskData[y][x]) {
|
||||||
|
violations++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Marker > mask pixels: " + violations);
|
||||||
|
|
||||||
|
morphologyState.setReconstruction(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void computeMedianFilter(int size) {
|
||||||
|
Image image = appState.getImage();
|
||||||
|
|
||||||
|
Image result = morphologyService.medianFilter(image, size);
|
||||||
|
|
||||||
|
morphologyState.setMedian(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dispose() {
|
||||||
|
view = null;
|
||||||
|
morphologyState.unsubscribe(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMaskChanged(Image mask) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGeodesicDilationChanged(Image image) {
|
||||||
|
if (view != null) {
|
||||||
|
view.updateDilation(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGeodesicReconstructionChanged(Image image) {
|
||||||
|
if (view != null) {
|
||||||
|
view.updateReconstruction(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMedianChanged(Image image) {
|
||||||
|
if (view != null) {
|
||||||
|
view.updateMedian(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,22 +22,21 @@ public class MorphologyService {
|
|||||||
return BasicMorphology.closing(image, size).toImage();
|
return BasicMorphology.closing(image, size).toImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Image geodesicDilation(Image image, Image mask, int size) {
|
public Image geodesicDilation(Image image, Image mask, int iterations) {
|
||||||
return ComplexMorphology
|
return ComplexMorphology
|
||||||
.geodesicDilation(image, mask, size)
|
.geodesicDilation(image, mask, iterations)
|
||||||
.toImage();
|
.toImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Image geodesicReconstruction(Image marker, Image mask, int size) {
|
public Image geodesicReconstruction(Image image, Image mask) {
|
||||||
return ComplexMorphology
|
return ComplexMorphology
|
||||||
.geodesicReconstruction(marker, mask, size)
|
.geodesicReconstruction(image, mask)
|
||||||
.toImage();
|
.toImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Image meanFilter(Image image, int size) {
|
public Image medianFilter(Image image, int size) {
|
||||||
return ComplexMorphology
|
return ComplexMorphology
|
||||||
.meanFilter(image, size)
|
.medianFilter(image, size)
|
||||||
.toImage();
|
.toImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
10
src/main/java/ui/abstractions/IComplexMorphologyView.java
Normal file
10
src/main/java/ui/abstractions/IComplexMorphologyView.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package ui.abstractions;
|
||||||
|
|
||||||
|
import domain.image.Image;
|
||||||
|
|
||||||
|
public interface IComplexMorphologyView {
|
||||||
|
void updateMask(Image mask);
|
||||||
|
void updateDilation(Image image);
|
||||||
|
void updateReconstruction(Image image);
|
||||||
|
void updateMedian(Image image);
|
||||||
|
}
|
||||||
@@ -254,6 +254,5 @@ public class NavBar extends JMenuBar implements INavBar {
|
|||||||
|
|
||||||
private void displayBasicMorphology(ActionEvent actionEvent) { presenter.goToBasicMorphology(); }
|
private void displayBasicMorphology(ActionEvent actionEvent) { presenter.goToBasicMorphology(); }
|
||||||
|
|
||||||
private void displayComplexeMorphology(ActionEvent actionEvent) {
|
private void displayComplexeMorphology(ActionEvent actionEvent) { presenter.goToComplexMorphology(); }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,17 +2,13 @@ package ui.implementation.views.morphology;
|
|||||||
|
|
||||||
import domain.image.Image;
|
import domain.image.Image;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import presenters.morphology.MorphologyPresenter;
|
import presenters.morphology.BasicMorphologyPresenter;
|
||||||
import ui.abstractions.AbstractView;
|
import ui.abstractions.AbstractView;
|
||||||
import ui.abstractions.IBasicMorphologyView;
|
import ui.abstractions.IBasicMorphologyView;
|
||||||
import ui.implementation.components.controls.SaveButton;
|
import ui.implementation.components.controls.SaveButton;
|
||||||
import ui.implementation.components.image.TabbedImagePanel;
|
import ui.implementation.components.image.TabbedImagePanel;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.text.AbstractDocument;
|
|
||||||
import javax.swing.text.AttributeSet;
|
|
||||||
import javax.swing.text.BadLocationException;
|
|
||||||
import javax.swing.text.DocumentFilter;
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
public class BasicMorphologyView extends AbstractView implements IBasicMorphologyView {
|
public class BasicMorphologyView extends AbstractView implements IBasicMorphologyView {
|
||||||
@@ -22,13 +18,13 @@ public class BasicMorphologyView extends AbstractView implements IBasicMorpholog
|
|||||||
private static final String OPENING_TAB_TITLE = "Ouverture";
|
private static final String OPENING_TAB_TITLE = "Ouverture";
|
||||||
private static final String CLOSING_TAB_TITLE = "Fermeture";
|
private static final String CLOSING_TAB_TITLE = "Fermeture";
|
||||||
|
|
||||||
private final MorphologyPresenter presenter;
|
private final BasicMorphologyPresenter presenter;
|
||||||
|
|
||||||
private TabbedImagePanel modeTab;
|
private TabbedImagePanel modeTab;
|
||||||
private JTextField maskSizeField;
|
private JSpinner maskSizeSpinner;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public BasicMorphologyView(MorphologyPresenter presenter) {
|
public BasicMorphologyView(BasicMorphologyPresenter presenter) {
|
||||||
this.presenter = presenter;
|
this.presenter = presenter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +37,9 @@ public class BasicMorphologyView extends AbstractView implements IBasicMorpholog
|
|||||||
modeTab.addPreviewTab(OPENING_TAB_TITLE);
|
modeTab.addPreviewTab(OPENING_TAB_TITLE);
|
||||||
modeTab.addPreviewTab(CLOSING_TAB_TITLE);
|
modeTab.addPreviewTab(CLOSING_TAB_TITLE);
|
||||||
|
|
||||||
maskSizeField = createPositiveIntegerField();
|
maskSizeSpinner = new JSpinner(
|
||||||
|
new SpinnerNumberModel(1, 1, Integer.MAX_VALUE, 2)
|
||||||
|
);
|
||||||
|
|
||||||
JButton applyButton = new JButton("Appliquer");
|
JButton applyButton = new JButton("Appliquer");
|
||||||
applyButton.addActionListener(e -> applyMorphology());
|
applyButton.addActionListener(e -> applyMorphology());
|
||||||
@@ -49,7 +47,7 @@ public class BasicMorphologyView extends AbstractView implements IBasicMorpholog
|
|||||||
JButton saveButton = new SaveButton();
|
JButton saveButton = new SaveButton();
|
||||||
|
|
||||||
JPanel controlPanel = createControlPanel(
|
JPanel controlPanel = createControlPanel(
|
||||||
maskSizeField,
|
maskSizeSpinner,
|
||||||
applyButton
|
applyButton
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -100,12 +98,17 @@ public class BasicMorphologyView extends AbstractView implements IBasicMorpholog
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initValues() {
|
public void initValues() {
|
||||||
this.modeTab.addChangeListener(e -> applyMorphology());
|
modeTab.addChangeListener(e -> applyMorphology());
|
||||||
|
|
||||||
presenter.setView(this);
|
presenter.setView(this);
|
||||||
|
|
||||||
applyMorphology();
|
applyMorphology();
|
||||||
}
|
}
|
||||||
|
|
||||||
private JPanel createControlPanel(JTextField sizeField, JButton applyButton) {
|
private JPanel createControlPanel(
|
||||||
|
JSpinner sizeSpinner,
|
||||||
|
JButton applyButton
|
||||||
|
) {
|
||||||
JPanel panel = new JPanel();
|
JPanel panel = new JPanel();
|
||||||
|
|
||||||
GroupLayout layout = new GroupLayout(panel);
|
GroupLayout layout = new GroupLayout(panel);
|
||||||
@@ -119,9 +122,9 @@ public class BasicMorphologyView extends AbstractView implements IBasicMorpholog
|
|||||||
layout.createParallelGroup(GroupLayout.Alignment.CENTER)
|
layout.createParallelGroup(GroupLayout.Alignment.CENTER)
|
||||||
.addComponent(label)
|
.addComponent(label)
|
||||||
.addComponent(
|
.addComponent(
|
||||||
sizeField,
|
sizeSpinner,
|
||||||
GroupLayout.PREFERRED_SIZE,
|
GroupLayout.PREFERRED_SIZE,
|
||||||
60,
|
70,
|
||||||
GroupLayout.PREFERRED_SIZE
|
GroupLayout.PREFERRED_SIZE
|
||||||
)
|
)
|
||||||
.addComponent(applyButton)
|
.addComponent(applyButton)
|
||||||
@@ -131,7 +134,7 @@ public class BasicMorphologyView extends AbstractView implements IBasicMorpholog
|
|||||||
layout.createSequentialGroup()
|
layout.createSequentialGroup()
|
||||||
.addComponent(label)
|
.addComponent(label)
|
||||||
.addComponent(
|
.addComponent(
|
||||||
sizeField,
|
sizeSpinner,
|
||||||
GroupLayout.PREFERRED_SIZE,
|
GroupLayout.PREFERRED_SIZE,
|
||||||
GroupLayout.DEFAULT_SIZE,
|
GroupLayout.DEFAULT_SIZE,
|
||||||
GroupLayout.PREFERRED_SIZE
|
GroupLayout.PREFERRED_SIZE
|
||||||
@@ -142,18 +145,8 @@ public class BasicMorphologyView extends AbstractView implements IBasicMorpholog
|
|||||||
return panel;
|
return panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JTextField createPositiveIntegerField() {
|
|
||||||
JTextField field = new JTextField("1", 5);
|
|
||||||
((AbstractDocument) field.getDocument()).setDocumentFilter(new PositiveIntegerFilter());
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void applyMorphology() {
|
private void applyMorphology() {
|
||||||
Integer size = getMaskSize();
|
int size = (Integer) maskSizeSpinner.getValue();
|
||||||
|
|
||||||
if (size == null || size % 2 == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (modeTab.getSelectedIndex()) {
|
switch (modeTab.getSelectedIndex()) {
|
||||||
case 0 -> presenter.computeErosion(size);
|
case 0 -> presenter.computeErosion(size);
|
||||||
@@ -163,32 +156,22 @@ public class BasicMorphologyView extends AbstractView implements IBasicMorpholog
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Integer getMaskSize() {
|
@Override
|
||||||
try {
|
|
||||||
int size = Integer.parseInt(maskSizeField.getText());
|
|
||||||
|
|
||||||
if (size <= 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateErosion(Image image) {
|
public void updateErosion(Image image) {
|
||||||
modeTab.loadImage(EROSION_TAB_TITLE, image);
|
modeTab.loadImage(EROSION_TAB_TITLE, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void updateDilation(Image image) {
|
public void updateDilation(Image image) {
|
||||||
modeTab.loadImage(DILATION_TAB_TITLE, image);
|
modeTab.loadImage(DILATION_TAB_TITLE, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void updateOpening(Image image) {
|
public void updateOpening(Image image) {
|
||||||
modeTab.loadImage(OPENING_TAB_TITLE, image);
|
modeTab.loadImage(OPENING_TAB_TITLE, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void updateClosing(Image image) {
|
public void updateClosing(Image image) {
|
||||||
modeTab.loadImage(CLOSING_TAB_TITLE, image);
|
modeTab.loadImage(CLOSING_TAB_TITLE, image);
|
||||||
}
|
}
|
||||||
@@ -198,31 +181,4 @@ public class BasicMorphologyView extends AbstractView implements IBasicMorpholog
|
|||||||
presenter.setView(null);
|
presenter.setView(null);
|
||||||
presenter.dispose();
|
presenter.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class PositiveIntegerFilter extends DocumentFilter {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr
|
|
||||||
) throws BadLocationException {
|
|
||||||
if (isValid(fb.getDocument().getText(0, fb.getDocument().getLength()), offset, 0, string)) {
|
|
||||||
super.insertString(fb, offset, string, attr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
|
|
||||||
if (isValid(fb.getDocument().getText(0, fb.getDocument().getLength()), offset, length, text)) {
|
|
||||||
super.replace(fb, offset, length, text, attrs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isValid(String current, int offset, int length, String replacement) {
|
|
||||||
String result = current.substring(0, offset) + replacement + current.substring(offset + length);
|
|
||||||
if (result.isEmpty()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.matches("[1-9][0-9]*");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
package ui.implementation.views.morphology;
|
||||||
|
|
||||||
|
import domain.image.Image;
|
||||||
|
import infrastructure.image.io.ImageLoader;
|
||||||
|
import infrastructure.ui.ImageMapper;
|
||||||
|
import jakarta.inject.Inject;
|
||||||
|
import presenters.morphology.ComplexMorphologyPresenter;
|
||||||
|
import ui.abstractions.AbstractView;
|
||||||
|
import ui.abstractions.IComplexMorphologyView;
|
||||||
|
import ui.implementation.components.controls.SaveButton;
|
||||||
|
import ui.implementation.components.image.TabbedImagePanel;
|
||||||
|
import ui.implementation.components.intent.FileChooser;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class ComplexMorphologyView extends AbstractView implements IComplexMorphologyView {
|
||||||
|
|
||||||
|
private static final String DILATION_TAB_TITLE = "Dilatation géodésique";
|
||||||
|
private static final String RECONSTRUCTION_TAB_TITLE = "Reconstruction géodésique";
|
||||||
|
private static final String MEDIAN_TAB_TITLE = "Filtre médian";
|
||||||
|
|
||||||
|
private final ComplexMorphologyPresenter presenter;
|
||||||
|
|
||||||
|
private TabbedImagePanel modeTab;
|
||||||
|
|
||||||
|
private JButton maskButton;
|
||||||
|
private JLabel maskLabel;
|
||||||
|
private JSpinner iterationsSpinner;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ComplexMorphologyView(ComplexMorphologyPresenter presenter) {
|
||||||
|
this.presenter = presenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initComponents() {
|
||||||
|
modeTab = new TabbedImagePanel();
|
||||||
|
|
||||||
|
modeTab.addPreviewTab(DILATION_TAB_TITLE);
|
||||||
|
modeTab.addPreviewTab(RECONSTRUCTION_TAB_TITLE);
|
||||||
|
modeTab.addPreviewTab(MEDIAN_TAB_TITLE);
|
||||||
|
|
||||||
|
iterationsSpinner = new JSpinner(
|
||||||
|
new SpinnerNumberModel(1, 1, Integer.MAX_VALUE, 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
maskButton = new JButton("Choisir...");
|
||||||
|
maskLabel = new JLabel("Aucun masque");
|
||||||
|
|
||||||
|
maskButton.addActionListener(e -> chooseGeodesicMask());
|
||||||
|
|
||||||
|
JButton applyButton = new JButton("Appliquer");
|
||||||
|
applyButton.addActionListener(e -> applyMorphology());
|
||||||
|
|
||||||
|
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("Traitement morphologique complexe");
|
||||||
|
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||||
|
pack();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initValues() {
|
||||||
|
modeTab.addChangeListener(e -> updateControls());
|
||||||
|
|
||||||
|
presenter.setView(this);
|
||||||
|
|
||||||
|
updateControls();
|
||||||
|
}
|
||||||
|
|
||||||
|
private JPanel createControlPanel(JButton applyButton) {
|
||||||
|
JPanel panel = new JPanel();
|
||||||
|
|
||||||
|
GroupLayout layout = new GroupLayout(panel);
|
||||||
|
panel.setLayout(layout);
|
||||||
|
layout.setAutoCreateGaps(true);
|
||||||
|
layout.setAutoCreateContainerGaps(true);
|
||||||
|
|
||||||
|
JLabel maskLabelTitle = new JLabel("Masque géodésique :");
|
||||||
|
JLabel iterationsLabel = new JLabel("Nombre d'itérations :");
|
||||||
|
|
||||||
|
layout.setHorizontalGroup(
|
||||||
|
layout.createParallelGroup(GroupLayout.Alignment.CENTER)
|
||||||
|
.addComponent(maskLabelTitle)
|
||||||
|
.addComponent(maskButton)
|
||||||
|
.addComponent(maskLabel)
|
||||||
|
.addComponent(iterationsLabel)
|
||||||
|
.addComponent(
|
||||||
|
iterationsSpinner,
|
||||||
|
GroupLayout.PREFERRED_SIZE,
|
||||||
|
70,
|
||||||
|
GroupLayout.PREFERRED_SIZE
|
||||||
|
)
|
||||||
|
.addComponent(applyButton)
|
||||||
|
);
|
||||||
|
|
||||||
|
layout.setVerticalGroup(
|
||||||
|
layout.createSequentialGroup()
|
||||||
|
.addComponent(maskLabelTitle)
|
||||||
|
.addComponent(maskButton)
|
||||||
|
.addComponent(maskLabel)
|
||||||
|
.addComponent(iterationsLabel)
|
||||||
|
.addComponent(
|
||||||
|
iterationsSpinner,
|
||||||
|
GroupLayout.PREFERRED_SIZE,
|
||||||
|
GroupLayout.DEFAULT_SIZE,
|
||||||
|
GroupLayout.PREFERRED_SIZE
|
||||||
|
)
|
||||||
|
.addComponent(applyButton)
|
||||||
|
);
|
||||||
|
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void chooseGeodesicMask() {
|
||||||
|
FileChooser chooser = new FileChooser("./");
|
||||||
|
|
||||||
|
if (chooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
File file = chooser.getSelectedFile();
|
||||||
|
loadImage(file);
|
||||||
|
maskLabel.setText(file.getName());
|
||||||
|
applyMorphology();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateControls() {
|
||||||
|
boolean geodesicOperation = modeTab.getSelectedIndex() == 0 || modeTab.getSelectedIndex() == 1;
|
||||||
|
|
||||||
|
maskButton.setEnabled(geodesicOperation);
|
||||||
|
maskLabel.setEnabled(geodesicOperation);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyMorphology() {
|
||||||
|
int operation = modeTab.getSelectedIndex();
|
||||||
|
int iterations = (Integer) iterationsSpinner.getValue();
|
||||||
|
|
||||||
|
switch (operation) {
|
||||||
|
case 0 -> presenter.computeGeodesicDilation(iterations);
|
||||||
|
case 1 -> presenter.computeGeodesicReconstruction();
|
||||||
|
case 2 -> presenter.computeMedianFilter(iterations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateMask(Image mask) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateDilation(Image image) {
|
||||||
|
modeTab.loadImage(DILATION_TAB_TITLE, image);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateReconstruction(Image image) {
|
||||||
|
modeTab.loadImage(RECONSTRUCTION_TAB_TITLE, image);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateMedian(Image image) {
|
||||||
|
modeTab.loadImage(MEDIAN_TAB_TITLE, image);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disposeCore() {
|
||||||
|
presenter.setView(null);
|
||||||
|
presenter.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadImage(File file) {
|
||||||
|
try {
|
||||||
|
Image mask = ImageLoader.loadImage(file);
|
||||||
|
presenter.setMask(mask);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
displayErrorMessage("Oups !", "Impossible de charger le masque");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayErrorMessage(String title, String message) {
|
||||||
|
JOptionPane.showMessageDialog(
|
||||||
|
this,
|
||||||
|
message,
|
||||||
|
title,
|
||||||
|
JOptionPane.ERROR_MESSAGE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
Reference in New Issue
Block a user