package fr.unistra.pelican.demos.applied.remotesensing; import java.util.Vector; import fr.unistra.pelican.Image; import fr.unistra.pelican.PelicanException; import fr.unistra.pelican.algorithms.arithmetic.Difference; import fr.unistra.pelican.algorithms.conversion.ColorImageFromMultiBandImage; import fr.unistra.pelican.algorithms.io.HdrImageLoad; import fr.unistra.pelican.algorithms.io.ImageLoader; import fr.unistra.pelican.algorithms.io.ImageSave; import fr.unistra.pelican.algorithms.io.MultipleImageLoad; import fr.unistra.pelican.algorithms.logical.AND; import fr.unistra.pelican.algorithms.logical.CompareConstant; import fr.unistra.pelican.algorithms.logical.CompareImage; import fr.unistra.pelican.algorithms.morphology.binary.BinaryGradient; import fr.unistra.pelican.algorithms.segmentation.ManualThresholding; import fr.unistra.pelican.algorithms.segmentation.RidlerThresholding; import fr.unistra.pelican.algorithms.segmentation.flatzones.BooleanConnectedComponentsLabeling; import fr.unistra.pelican.algorithms.segmentation.labels.LabelsToRandomColors; import fr.unistra.pelican.algorithms.segmentation.labels.RegionSize; import fr.unistra.pelican.algorithms.visualisation.Viewer2D; import fr.unistra.pelican.util.morphology.FlatStructuringElement2D; public class CoastalAnalysisDemo { public static int ZONE = 0; public static int COMP = 1; public static int DIFF = 2; public static int COMP_DIFF = 3; public static boolean SAVE = false; public static boolean VIEW = true; int zone; String path = "/home/lefevre/data/global/teledetection/ecosgil/villerville/"; String test = path + "tests/"; String files[] = { "Zone3_MSS_60mC_25061976", // 60m 4 bandes "Zone3_ETM_30mC_13092002", // 30m 6 bandes "Zone3_ETM_30mC_21072000", // 30m 6 bandes "Zone3_TM_30mC_20051992", // 30m 6 bandes "Zone3_Spot_20m_24051987", // 20m 3 bandes "Zone3_Spot_20m_29061993", // 20m 3 bandes "Zone3_Aster_15m_050603", // 15m 3 bandes "Zone3_Aster_15m_250903", // 15m 3 bandes "Zone3_ETM_15mP_13092002", // 15m 1 bande "Zone3_ETM_15mP_21072000", // 15m 1 bande "Zone3_Spot5_10mC_230303", // 10m 3 bandes "Zone3_QB-MS_L1_ortho5m_261002", // 5m 4 bandes "Zone3_Gram_Spot5_5mC_230303", // 5m 3 bandes "Zone3_Spot5_5mP_230303", // 5m 1 bande "mnt_villerville_l1_5m", // 5m MNT 1 bande "Zone3_Spot5_2-5mP_23032003", // 2.5m 1 bande "Zone3_QB_2-4mC_26102002_ortho5m", // 2.4m 4 bandes "Zone3_QB_0-6mP_26102002_ortho5m", // 0.6m 1 bande }; public void displayFiles() { System.out.println("Fichiers disponibles"); for (int i = 0; i < files.length; i++) System.out.println(i + ":\t" + files[i]); } public void displaySyntax() { System.out.println("CoastalDetectionDemo : consulter la documentation"); } public CoastalAnalysisDemo() { zone = ZONE; } /** * @param args */ public static void main(String[] args) throws PelicanException { CoastalAnalysisDemo demo = new CoastalAnalysisDemo(); // Affichage des fichiers if (args.length == 1 && args[0].equalsIgnoreCase("help")) demo.displayFiles(); // Utilisation du travail de TER else if (args.length == 1 && args[0].equalsIgnoreCase("ter")) demo.etudeFiegelKamblockETM(); // Traitement d'une image binaire else if (args.length == 2 && args[0].equalsIgnoreCase("process")) demo.processZone(args[1]); // Choix d'une zone else if (args.length == 2 && args[0].equalsIgnoreCase("zone")) demo.etudeZone(Integer.parseInt(args[1])); else demo.displaySyntax(); } public void etudeZone(int z) { zone = z; long t1 = System.currentTimeMillis(); System.out.println("chargement"); Image rs = HdrImageLoad.exec(path + files[zone] + ".hdr"); System.out.println("affichage"); Viewer2D.exec(rs, "Villerville image #" + zone); System.out.println("sauvegarde"); if (rs.getBDim() == 1 || rs.getBDim() == 3) ImageSave.exec(rs, path + files[zone] + ".png"); else for (int i = 0; i < rs.getBDim(); i++) for (int j = 0; j < rs.getBDim(); j++) for (int k = 0; k < rs.getBDim(); k++) ImageSave.exec(ColorImageFromMultiBandImage.exec(rs, i, j, k), path + files[zone] + "-" + i + j + k + ".png"); System.out.println("seuillage"); thresholdBands(rs); System.out.println("comparaison"); compareBands(rs, COMP_DIFF, 2); long t2 = System.currentTimeMillis() - t1; System.out.println("Dmo termine : " + (t2 / 1000) + " secondes"); } public void processZone(String file) { long t1 = System.currentTimeMillis(); System.out.println("chargement"); Image rs = ImageLoader.exec(file); rs = RidlerThresholding.exec(rs); System.out.println("affichage"); Viewer2D.exec(rs, "Binarisation"); System.out.println("local"); ImageSave.exec(local(rs, 2), "local.png"); System.out.println("global"); ImageSave.exec(global(rs), "global.png"); long t2 = System.currentTimeMillis() - t1; System.out.println("Dmo termine : " + (t2 / 1000) + " secondes"); } public void etudeFiegelKamblockETM() { // Chargement String path = "/home/lefevre/data/global/teledetection/etm30m"; Image rs = MultipleImageLoad.exec(path, Image.B); // Sous-chantillonage effectuer les tests ou gnrer les images // rs=Subsampling.process(rs,4,4,1,1,1,Subsampling.AVERAGE); // Etude prliminaire: comparaison des bandes et seuillages thresholdBands(rs); compareBands(rs, COMP_DIFF, 0); // Binarisation Image binaryKamblock = compareAndTreshold(rs, 4, 5, 14); ImageSave.exec(binaryKamblock, "binaryKamblock.png"); Image binaryFiegel = singleThreshold(rs, 3, 28); ImageSave.exec(binaryFiegel, "binaryFiegel.png"); // Analyse de l'image binaire Image resultKamblock = global(binaryKamblock); ImageSave.exec(resultKamblock, "resultKamblock.png"); Image resultFiegel = local(binaryFiegel, 50); ImageSave.exec(resultFiegel, "resultFiegel.png"); } void thresholdBands(Image rs) { for (int i = 0; i < rs.getBDim(); i++) ImageSave.exec(RidlerThresholding.exec(rs.getImage4D(i, Image.B), false), test + files[zone] + "/" + "thr-" + (i + 1) + ".png"); } void compareBands(Image img, int operation, int threshold) { Image rs = img; if (threshold != 1) { for (int i = 0; i < rs.getBDim(); i++) for (int j = 0; j < rs.getBDim(); j++) if (i != j) { if (operation == COMP || operation == COMP_DIFF) ImageSave.exec(CompareImage.exec(rs.getImage4D(i, Image.B), rs.getImage4D(j, Image.B), CompareImage.GEQ), test + files[zone] + "/" + "comp-" + i + "-" + j + ".png"); if (operation == DIFF || operation == COMP_DIFF) ImageSave.exec(Difference.exec(rs.getImage4D(i, Image.B), rs.getImage4D(j, Image.B), true), test + files[zone] + "/" + "diff-" + i + "-" + j + ".png"); } } if (threshold != 0) { for (int i = 0; i < rs.getBDim(); i++) for (int j = 0; j < rs.getBDim(); j++) if (i != j) { if (operation == COMP || operation == COMP_DIFF) ImageSave.exec(CompareImage.exec(rs.getImage4D(i, Image.B), rs.getImage4D(j, Image.B), CompareImage.GEQ), test + files[zone] + "/" + "comps-" + i + "-" + j + ".png"); if (operation == DIFF || operation == COMP_DIFF) ImageSave.exec(RidlerThresholding.exec(Difference .exec(rs.getImage4D(i, Image.B), rs .getImage4D(j, Image.B), true), false), test + files[zone] + "/" + "diffs-" + i + "-" + j + ".png"); } } } Image compareAndTreshold(Image img, int i, int j, int seuil) { Image rs = img; Image bandA = rs.getImage4D(i - 1, Image.B); Image bandB = rs.getImage4D(j - 1, Image.B); // Segmentation Image comp1 = CompareImage.exec(bandA, bandB, CompareImage.GEQ); Image comp2 = null; if (seuil == -1) comp2 = RidlerThresholding.exec(bandA, false); else comp2 = CompareConstant.exec(bandA, seuil, CompareImage.SUP); Image res = AND.exec(comp1, comp2); if (SAVE) ImageSave.exec(res, test + files[zone] + "/" + "comps-" + i + "-" + j + ".png"); return res; } Image singleThreshold(Image rs, int band, int seuil) { // Seuillage de l'image Image img = rs.getImage4D(band - 1, Image.B); if (seuil == -1) img = RidlerThresholding.exec(img, false); else img = ManualThresholding.exec(img, seuil); if (SAVE) ImageSave.exec(img, test + files[zone] + "/" + "bands-" + band + ".png"); return img; } Image global(Image img) { Image res = img.copyImage(true); // Filtrage for (int k = 1; k < 16; k++) { // res=BinaryErosion.process(res,FlatStructuringElement.createFrameFlatStructuringElement(2*i+1)); // res=BinaryDilation.process(res,FlatStructuringElement.createFrameFlatStructuringElement(2*i+1)); filter(res, k, true); filter(res, k, false); } if (SAVE) ImageSave.exec(res, "global-filtered.png"); res = BinaryGradient.exec(res, FlatStructuringElement2D .createSquareFlatStructuringElement(2)); if (SAVE) ImageSave.exec(res, "global-gradient.png"); // Etiquetage en composantes connexes frame(res, false); res = BooleanConnectedComponentsLabeling.exec(res, BooleanConnectedComponentsLabeling.CONNEXITY8); // Conservation de la plus grande rgion (le trait de cte par // hypothse) int tailles[] = RegionSize.exec(res); int max = 1; for (int t = 1; t < tailles.length; t++) if (tailles[max] < tailles[t]) max = t; for (int p = 0; p < res.size(); p++) if (res.getPixelInt(p) != 0) if (res.getPixelInt(p) == max) res.setPixelInt(p, 1); else res.setPixelInt(p, 2); // Affichage en pseudo-couleur res = LabelsToRandomColors.exec(res, true); if (SAVE) ImageSave.exec(res, "global-result.png"); if (VIEW) Viewer2D.exec(res, "global-result"); return res; } void frame(Image img, boolean white) { for (int x = 0; x < img.getXDim(); x++) { img.setPixelXYBoolean(x, 0, white); img.setPixelXYBoolean(x, img.getYDim() - 1, white); } for (int y = 0; y < img.getYDim(); y++) { img.setPixelXYBoolean(0, y, white); img.setPixelXYBoolean(img.getXDim() - 1, y, white); } } void filter(Image img, int size, boolean white) { boolean stop; for (int x = size; x < img.getXDim() - size; x++) for (int y = size; y < img.getYDim() - size; y++) if (img.getPixelXYBoolean(x, y) == white) { stop = false; for (int i = 0; i < size * 2 && !stop; i++) if (img.getPixelXYBoolean(x + i - size, y - size) == white || img .getPixelXYBoolean(x + i - size, y + size) == white || img .getPixelXYBoolean(x - size, y + i - size) == white || img .getPixelXYBoolean(x + size, y + i - size) == white) stop = true; if (!stop) img.setPixelXYBoolean(x, y, !white); } } Image local(Image img, int grille) { // Initialisation des graines int xDim = img.getXDim(); int yDim = img.getYDim(); Image res = img.copyImage(false); int nbre = 0; int[][] graines = new int[(xDim / grille) * (yDim / grille)][2]; for (int i = 0; i < xDim - grille; i += grille) for (int j = 0; j < yDim - grille; j += grille) { graines[nbre][0] = i; graines[nbre][1] = j; nbre++; } // Filtrage des graines for (int i = 0; i < nbre; i++) { if (img.getPixelBoolean(graines[i][0], graines[i][1], 0, 0, 0)) res .setPixelBoolean(graines[i][0], graines[i][1], 0, 0, 0, true); if (graines[i][0] + grille < xDim) if (img.getPixelBoolean(graines[i][0] + grille, graines[i][1], 0, 0, 0)) res.setPixelBoolean(graines[i][0], graines[i][1], 0, 0, 0, false); if (graines[i][1] + grille < yDim) if (img.getPixelBoolean(graines[i][0], graines[i][1] + grille, 0, 0, 0)) res.setPixelBoolean(graines[i][0], graines[i][1], 0, 0, 0, false); } if (SAVE) ImageSave.exec(res, "local-filtered.png"); nbre = 0; // Mise jour des graines for (int i = 0; i < xDim; i++) for (int j = 0; j < yDim; j++) if (res.getPixelBoolean(i, j, 0, 0, 0)) { graines[nbre][0] = i; graines[nbre][1] = j; nbre++; res.setPixelBoolean(i, j, 0, 0, 0, false); } if (SAVE) ImageSave.exec(res, "local-updated.png"); // Rercherche pour chacune des graines for (int z = 0; z < nbre; z++) if (!res.getPixelBoolean(graines[z][0], graines[z][1], 0, 0, 0)) { int posX = graines[z][0]; int posY = graines[z][1]; res.setPixelBoolean(posX, posY, 0, 0, 0, true); Vector<Object> mouvements = new Vector<Object>(); int debut = -1; int nord = 0; int nordEst = 1; int est = 2; int sudEst = 3; int sud = 4; int sudOuest = 5; int ouest = 6; int nordOuest = 7; mouvements.addElement(debut); while (!mouvements.isEmpty()) { Integer lastMouv = (Integer) mouvements.lastElement(); boolean pos0 = false, pos1 = false, pos2 = false, pos3 = false, pos4 = false, pos5 = false, pos6 = false, pos7 = false; if (posY > 0) pos0 = img.getPixelBoolean(posX, posY - 1, 0, 0, 0); if (posX < (xDim - 1) && posY > 0) pos1 = img.getPixelBoolean(posX + 1, posY - 1, 0, 0, 0); if (posX < (xDim - 1)) pos2 = img.getPixelBoolean(posX + 1, posY, 0, 0, 0); if (posX < (xDim - 1) && posY < (yDim - 1)) pos3 = img.getPixelBoolean(posX + 1, posY + 1, 0, 0, 0); if (posY < (yDim - 1)) pos4 = img.getPixelBoolean(posX, posY + 1, 0, 0, 0); if (posX > 0 && posY < (yDim - 1)) pos5 = img.getPixelBoolean(posX - 1, posY + 1, 0, 0, 0); if (posX > 0) pos6 = img.getPixelBoolean(posX - 1, posY, 0, 0, 0); if (posX > 0 && posY > 0) pos7 = img.getPixelBoolean(posX - 1, posY - 1, 0, 0, 0); if (pos7 && !res .getPixelBoolean(posX - 1, posY - 1, 0, 0, 0) && (!pos0 || !pos6)) { res.setPixelBoolean(posX - 1, posY - 1, 0, 0, 0, true); mouvements.addElement(nordOuest); posX--; posY--; } else if (pos6 && !res.getPixelBoolean(posX - 1, posY, 0, 0, 0) && (!pos7 || !pos5)) { res.setPixelBoolean(posX - 1, posY, 0, 0, 0, true); mouvements.addElement(ouest); posX--; } else if (pos5 && !res .getPixelBoolean(posX - 1, posY + 1, 0, 0, 0) && (!pos4 || !pos6)) { res.setPixelBoolean(posX - 1, posY + 1, 0, 0, 0, true); mouvements.addElement(sudOuest); posX--; posY++; } else if (pos4 && !res.getPixelBoolean(posX, posY + 1, 0, 0, 0) && (!pos3 || !pos5)) { res.setPixelBoolean(posX, posY + 1, 0, 0, 0, true); mouvements.addElement(sud); posY++; } else if (pos3 && !res .getPixelBoolean(posX + 1, posY + 1, 0, 0, 0) && (!pos2 || !pos4)) { res.setPixelBoolean(posX + 1, posY + 1, 0, 0, 0, true); mouvements.addElement(sudEst); posX++; posY++; } else if (pos2 && !res.getPixelBoolean(posX + 1, posY, 0, 0, 0) && (!pos1 || !pos3)) { res.setPixelBoolean(posX + 1, posY, 0, 0, 0, true); mouvements.addElement(est); posX++; } else if (pos1 && !res .getPixelBoolean(posX + 1, posY - 1, 0, 0, 0) && (!pos0 || !pos2)) { res.setPixelBoolean(posX + 1, posY - 1, 0, 0, 0, true); mouvements.addElement(nordEst); posX++; posY--; } else if (pos0 && !res.getPixelBoolean(posX, posY - 1, 0, 0, 0) && (!pos7 || !pos1)) { res.setPixelBoolean(posX, posY - 1, 0, 0, 0, true); mouvements.addElement(nord); posY--; } else { mouvements.removeElementAt(mouvements.size() - 1); int i = lastMouv.intValue(); switch (i) { case 0: posY++; break; case 1: posY++; posX--; break; case 2: posX--; break; case 3: posX--; posY--; break; case 4: posY--; break; case 5: posX++; posY--; break; case 6: posX++; break; case 7: posX++; posY++; break; } } } } if (SAVE) ImageSave.exec(res, "local-result.png"); if (VIEW) Viewer2D.exec(res, "local-result"); return res; } }