Bonjour a tous,

J'ai un problème de stack overflow et après 2h de recherche j'abandonne un peu.

Je crée un objet pour segmenter une image, j'appel la méthode 'process' qui se charge d'appeler une autre fonction 'lookForRegion' pour trouver une région entière et isolée de mon image. Cette région correspond aux pixels non blancs situés dans l'image. Je ne sais pas vraiment ce qu'il se passe et je ne pense pas que cela vienne de la récursion.

Edit: Il semblerait que cela vienne du typage de l'image.

... Un peu d'aide serait la bienvenue :)

Voici mes 2 classes:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
public class Segment {
    private int X, Y;
    private int nbBlackPixel = 0;
    private BufferedImage main = null;
    private List<Region> ltmp = new LinkedList<Region>();
    private List<Region> lr = new LinkedList<Region>();
 
    public Segment(BufferedImage image) {
        main = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
        // Copy
        Graphics g = main.createGraphics();
        g.drawImage(image, 0, 0, null);
        g.dispose();
        X = Y = 20;
    }
 
    public void lookForRegion(Region r, int x, int y) {
        if ((main.getRGB(x, y) & 0xff) == 0xff) {
            System.out.println("What?");
            return ;
        }
        nbBlackPixel++;
        r.addPixel(x, y, 0xff000000); // Create pixel in new region (set black)
        main.setRGB(x, y, 0xffffffff); // Erase pixel from main image (set white)
        if ((x + 1) < (Misc.IMAGE_WIDTH - X) && (main.getRGB(x + 1, y) & 0xff) < 0xff) {
            lookForRegion(r, x + 1, y);
        }
        if ((x - 1) > X && (main.getRGB(x - 1, y) & 0xff) < 0xff) {
            lookForRegion(r, x - 1, y);
        }
        if ((y + 1) < (Misc.IMAGE_HEIGHT - Y) && (main.getRGB(x, y + 1) & 0xff) < 0xff) {
            lookForRegion(r, x, y + 1);
        }
        if ((y - 1) > Y && (main.getRGB(x, y - 1) & 0xff) < 0xff) {
            lookForRegion(r, x, y - 1);
        }
        r.save();
        return ;
    }
 
    // Main loop
    public void process() {
        int n = 1;
        for (int y = Y ; y < Misc.IMAGE_HEIGHT - Y ; y++) {
            for (int x = X ; x < Misc.IMAGE_WIDTH - X ; x++) {
                if ((main.getRGB(x, y) & 0xff) < 0xff) { // If not white
                    // Create new region
                    System.out.println("New region spotted");
                    Region r = new Region(n, Misc.IMAGE_WIDTH, Misc.IMAGE_HEIGHT);
                    lookForRegion(r, x, y);
                    System.out.println("End of research of the region");
                    if (validRegion(r))
                        lr.add(r);
                    n++;
                }
            }
        }
        mergeRegions();
    }
 
    public List<Region> getRegions() {
        return lr;
    }
 
    public void mergeRegions() {
        for (int i = 0 ; i < lr.size() ; i++) {
            Region r = lr.get(i);
            if (!r.isActivated()) {
                for (int j = 0 ; j < lr.size() ; j++) {
                    Region r2 = lr.get(j);
                    if (!r2.isActivated()) {
                        r.tryMerge(r2);
                    }
                }
                ltmp.add(r);
            }
        }
        lr = ltmp;
    }
 
    // @todo take relative number of pixel
    public boolean validRegion(Region r) {
        System.out.println("Is Size OK? :"  + r.isSizeOK());
        System.out.println("Number of black pixels : " + r.getNbOfBlackPixels());
        System.out.println("Size : " + r.getPosition().getWidth() + "x" + r.getPosition().getHeight());
        if (r.getNbOfBlackPixels() <= 100)
            return r.isSizeOK();
        return true;
    }
 
    public void save() {
        for (Region r : lr) {
            r.truncate();
            r.save();
        }
    }
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
 
public class Region {
    private boolean areMostSet = false, activated = false;
    private int nb, nbOfBlackPixels;//, mostLeft, mostRight, mostUp, mostDown;
    private Position p;
    private BufferedImage image;
 
    public Region(int nb, int width, int height) {
        this.nb = nb;
        p = new Position();
        nbOfBlackPixels = 0;
        image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
        Graphics g = image.createGraphics();
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, width, height);
    }
 
    public void addPixel(int x, int y, int c) {
        if (c == 0xff000000 || c == 0) {
            nbOfBlackPixels++;
            if (p.mostLeft > x || !areMostSet)
                p.mostLeft = x;
            if (p.mostRight < x || !areMostSet)
                p.mostRight = x;
            if (p.mostUp > y || !areMostSet)
                p.mostUp = y;
            if (p.mostDown < y || !areMostSet)
                p.mostDown = y;
            if (!areMostSet)
                areMostSet = true;
            image.setRGB(x, y, 0xff000000);
        }
    }
 
    public void truncate() {
        image = image.getSubimage(p.mostLeft, p.mostUp, p.getWidth(), p.getHeight());
    }
 
    public BufferedImage getImage() {
        return image;
    }
 
    public int getNumber() {
        return nb;
    }
 
    public Position getPosition() {
        return p;
    }
 
    public void save() {
        Main.save(image, "region_" + nb + ".png");
    }
 
    public int getNbOfBlackPixels() {
        return nbOfBlackPixels;
    }
 
    public void reassignNumber() {
        nb = p.mostLeft;
    }
 
    public void reposition() {
        nbOfBlackPixels = 0;
        areMostSet = false;
        BufferedImage imageTmp = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
        imageTmp.setData(image.getRaster());
        Graphics g = image.createGraphics();
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, imageTmp.getWidth(), imageTmp.getHeight());
        for (int x = 0 ; x < imageTmp.getWidth() ; x++)
            for (int y = 0 ; y < imageTmp.getHeight() ; y++)
                addPixel(x, y, imageTmp.getRGB(x, y));
    }
 
    // @todo Take relative size
    // @todo Implement resegmentation
    public boolean isSizeOK() {
        //System.out.println("Size : " + p.getWidth() +" x " + p.getHeight());
        if (p.getWidth() > 15 || p.getHeight() > 20) {
            if (p.getWidth() > 100)
                return false;
            else if (p.getWidth() > 60) {
                // Try to remove noise
                Median.getInstance().init(image, 5);
                image = Median.getInstance().filter();
                // Recalculate position
                reposition();
                // if (size still not OK --> segment)
                if (p.getWidth() > 60)
                    return false;
                return true;
            }
            else
                return true;
        }
        return false;
    }
 
    public void setState(boolean m) {
        activated = m;
    }
 
    public boolean isActivated() {
        return activated;
    }
 
    private void merge(Region r) {
        r.setState(true);
        for (int y = 0 ; y < Misc.IMAGE_HEIGHT ; y++)
            for (int x = 0 ; x < Misc.IMAGE_WIDTH ; x++) {
                int c = r.getImage().getRGB(x, y);
                if (c == 0xff000000)
                    image.setRGB(x, y, c);
            }
    }
 
    // @todo copy the one which has the higher number of black pixels ??
    public void tryMerge(Region r) {
        if (p.contains(r.getPosition())) {
            merge(r);
        }
    }
}
Et voici ma stack trace:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
 
New region spotted
Exception in thread "main" java.lang.StackOverflowError
        at java.awt.image.ComponentColorModel.getRGBComponent(ComponentColorModel.java:885)
        at java.awt.image.ComponentColorModel.getRed(ComponentColorModel.java:927)
        at java.awt.image.ComponentColorModel.getRGB(ComponentColorModel.java:1118)
        at java.awt.image.BufferedImage.getRGB(BufferedImage.java:871)
        at binarisationtests.Segment.lookForRegion(Segment.java:34)
        at binarisationtests.Segment.lookForRegion(Segment.java:42)
        at binarisationtests.Segment.lookForRegion(Segment.java:42)
        at binarisationtests.Segment.lookForRegion(Segment.java:42)
Edit 2: Il semblerait que mon problème venait de ma copie d'image (un peu 'cradosse') dans mes classes de traitement d'image, j'ai tout remis au clair et ça marche. \o/