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(); } } }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
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); } } }
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/
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)
Partager