Libraryless. Click here for Pure Java version (13025L/76K).
1 | // grayscale, actually |
2 | sclass BWIntegralImage > Meta implements IBWIntegralImage, IIntegralImage { |
3 | int w, h; |
4 | int[] data; // 1 entry per pixel |
5 | ifdef BWIntegralImage_CountAccesses |
6 | long accesses; |
7 | endifdef |
8 | |
9 | // constructors |
10 | |
11 | *() {} |
12 | *(File f) { this(loadImage2(f)); } |
13 | *(MakesBufferedImage img) { this(toBufferedImage(img)); } |
14 | *(BufferedImage image) { grab(image); } |
15 | *(BufferedImage image, Decolorizer decolorizer) { grab(image, decolorizer); } |
16 | *(GrabbableIntPixels gp) { grab(gp); } |
17 | *(GrabbableRGBBytePixels gp) { grab(gp, new Decolorizer.Simple); } |
18 | *(GrabbableGrayPixels gp) { grab(gp); } |
19 | |
20 | *(BWImage img) { |
21 | grab(new GrabbableGrayPixels(img.pixels, img.width, img.height, |
22 | 0, img.width); |
23 | } |
24 | |
25 | // grab functions |
26 | |
27 | void grab(BufferedImage image, Decolorizer decolorizer default null) { |
28 | if (image.getType() == BufferedImage.TYPE_BYTE_GRAY) |
29 | grab(grabbableGrayPixels(image)); |
30 | else { // rgb image |
31 | var gp = grabbableRGBBytePixels(image); |
32 | if (gp != null) |
33 | grab(gp, decolorizer); |
34 | else |
35 | grab(grabbableIntPixels_fastOrSlow(image), decolorizer); |
36 | } |
37 | } |
38 | |
39 | void grab(GrabbableRGBBytePixels gp, Decolorizer decolorizer) { |
40 | if (decolorizer == null) decolorizer = new Decolorizer.Simple; |
41 | |
42 | alloc(gp.w, gp.h); |
43 | int w = this.w, h = this.h; |
44 | ifdef BWIntegralImage_debug |
45 | print("BWIntegralImage grabbing: " + gp); |
46 | endifdef |
47 | |
48 | // first row |
49 | |
50 | int iImage = gp.offset, sum = 0, pixelStride = gp.pixelStride; |
51 | byte[] image = gp.data; |
52 | for x to w: { |
53 | int packed = rgbInt(image[iImage], image[iImage+1], image[iImage+2]); |
54 | iImage += pixelStride; |
55 | int brightness = decolorizer.toGrayScale(packed); |
56 | data[x] = (sum += brightness); |
57 | } |
58 | |
59 | // subsequent rows |
60 | |
61 | var ping = pingSource(); |
62 | int scanlineExtra = gp.scanlineStride-w*pixelStride; |
63 | iImage = gp.offset+gp.scanlineStride; |
64 | int i = w; |
65 | for (int y = 1; y < h; y++) { |
66 | sum = 0; |
67 | for x to w: { |
68 | int packed = rgbInt(image[iImage], image[iImage+1], image[iImage+2]); |
69 | iImage += pixelStride; |
70 | int brightness = decolorizer.toGrayScale(packed); |
71 | sum += brightness; |
72 | data[i] = sum + data[i-w]; |
73 | i++; |
74 | } |
75 | |
76 | iImage += scanlineExtra; |
77 | ping?!; |
78 | } // for y |
79 | } |
80 | |
81 | void grab(GrabbableIntPixels gp, Decolorizer decolorizer) { |
82 | if (isDefaultDecolorizer(decolorizer)) |
83 | ret with grab(gp); |
84 | |
85 | alloc(gp.w, gp.h); |
86 | int w = this.w, h = this.h; |
87 | ifdef BWIntegralImage_debug |
88 | print("BWIntegralImage grabbing: " + gp); |
89 | endifdef |
90 | int offset = gp.offset, sum = 0; |
91 | int[] image = gp.data; |
92 | for x to w: { |
93 | int packed = image[offset+x]; |
94 | int brightness = decolorizer.toGrayScale(packed); |
95 | data[x] = (sum += brightness); |
96 | } |
97 | |
98 | var ping = pingSource(); |
99 | int scanlineExtra = gp.scanlineStride-w; |
100 | int iImage = offset+gp.scanlineStride, i = w; |
101 | for (int y = 1; y < h; y++) { |
102 | sum = 0; |
103 | for x to w: { |
104 | int packed = image[iImage]; |
105 | int brightness = decolorizer.toGrayScale(packed); |
106 | sum += brightness; |
107 | data[i] = sum + data[i-w]; |
108 | iImage++; i++; |
109 | } |
110 | |
111 | iImage += scanlineExtra; |
112 | ping?!; |
113 | } // for y |
114 | } |
115 | |
116 | void grab(GrabbableIntPixels gp) { |
117 | alloc(gp.w, gp.h); |
118 | int w = this.w, h = this.h; |
119 | ifdef BWIntegralImage_debug |
120 | print("BWIntegralImage grabbing: " + gp); |
121 | endifdef |
122 | int offset = gp.offset, sum = 0; |
123 | int[] image = gp.data; |
124 | for x to w: { |
125 | int packed = image[offset+x]; |
126 | int brightness = packedToBrightness(packed); |
127 | data[x] = (sum += brightness); |
128 | } |
129 | |
130 | var ping = pingSource(); |
131 | int scanlineExtra = gp.scanlineStride-w; |
132 | int iImage = offset+gp.scanlineStride, i = w; |
133 | for (int y = 1; y < h; y++) { |
134 | sum = 0; |
135 | for x to w: { |
136 | int packed = image[iImage]; |
137 | int brightness = packedToBrightness(packed); |
138 | sum += brightness; |
139 | data[i] = sum + data[i-w]; |
140 | iImage++; i++; |
141 | } |
142 | |
143 | iImage += scanlineExtra; |
144 | ping?!; |
145 | } // for y |
146 | } |
147 | |
148 | void grab(GrabbableGrayPixels gp) { |
149 | alloc(gp.w, gp.h); |
150 | ifdef BWIntegralImage_debug |
151 | print("BWIntegralImage grabbing: " + gp); |
152 | endifdef |
153 | int offset = gp.offset, sum = 0; |
154 | byte[] image = gp.data; |
155 | for x to w: { |
156 | int brightness = image[offset+x]; |
157 | data[x] = (sum += brightness); |
158 | } |
159 | |
160 | var ping = pingSource(); |
161 | int scanlineExtra = gp.scanlineStride-w; |
162 | int iImage = offset+gp.scanlineStride, i = w; |
163 | for (int y = 1; y < h; y++) { |
164 | sum = 0; |
165 | for x to w: { |
166 | int brightness = image[iImage]; |
167 | sum += brightness; |
168 | data[i] = sum + data[i-w]; |
169 | iImage++; i++; |
170 | } |
171 | |
172 | iImage += scanlineExtra; |
173 | ping?!; |
174 | } // for y |
175 | } |
176 | |
177 | private void alloc(int w, int h) { |
178 | this.w = w; |
179 | this.h = h; |
180 | if (w*h > 8*1024*1024) |
181 | fail("Image too large (more than 8 MP): " + w + "*" + h); |
182 | data = new int[w*h]; |
183 | } |
184 | |
185 | // pixels outside of image are considered black |
186 | int get(int x, int y) { |
187 | ifdef BWIntegralImage_CountAccesses |
188 | ++accesses; |
189 | endifdef |
190 | ret x < 0 || y < 0 ? 0 |
191 | : data[min(y, h-1)*w+min(x, w-1)]; |
192 | } |
193 | |
194 | // precise version [TO TEST!] |
195 | public double getIIValue(double x, double y) { |
196 | int xFloor = ifloor(x), yFloor = ifloor(y); |
197 | double val = getIIValue(xFloor, yFloor); |
198 | |
199 | // at integer coordinate? |
200 | if (xFloor == x && yFloor == y) |
201 | ret val; |
202 | |
203 | // at non-integer coordinate, perform subpixel calculation |
204 | double val2 = getIIValue(xFloor+1, yFloor); |
205 | double val3 = getIIValue(xFloor , yFloor+1); |
206 | double val4 = getIIValue(xFloor+1, yFloor+1); |
207 | |
208 | ret blend2D(val, val2, val3, val4, x-xFloor, y-yFloor); |
209 | } |
210 | |
211 | public int getIIValue(int x, int y) { ret get(x, y); } |
212 | public double getIntegralValue(int x, int y, int channel) { |
213 | ret get(x, y); |
214 | } |
215 | |
216 | public double getPixelAverage(int x1, int y1, int x2, int y2) { |
217 | int area = (x2-x1)*(y2-y1); |
218 | ret doubleRatio(bwIntegralImage_sumRect(this, x1, y1, x2, y2), area); |
219 | } |
220 | |
221 | public int getWidth() { ret w; } |
222 | public int getHeight() { ret h; } |
223 | |
224 | int packedToBrightness(int packed) { |
225 | int b = (packed & 0xFF); |
226 | ifdef BWIntegralImage_brightnessCheat |
227 | ret b; |
228 | endifdef |
229 | ifndef BWIntegralImage_brightnessCheat |
230 | int r = ((packed >> 16) & 0xFF); |
231 | int g = ((packed >> 8) & 0xFF); |
232 | ret (r+g+b+1)/3; |
233 | endifndef |
234 | } |
235 | |
236 | // get brightness of pixel |
237 | public int getInt(int x, int y) { |
238 | ret iround(rectSum(x, y, x+1, y+1, 0)); |
239 | } |
240 | |
241 | // returns RGB pixel without alpha |
242 | public int getPixel(int x, int y) { |
243 | ret rgbIntFromGrayscale(getInt(x, y)); |
244 | } |
245 | |
246 | public BufferedImage getBufferedImage() { |
247 | //ret scaleDownUsingIntegralImageBW(this, w).getBufferedImage(); |
248 | O src = metaGet src(this); |
249 | if (src cast BufferedImage) ret src; |
250 | |
251 | ret grayImageFromIBWIntegralImage(this); |
252 | } |
253 | } |
Began life as a copy of #1019588
download show line numbers debug dex old transpilations
Travelled to 14 computer(s): bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mowyntqkapby, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv
No comments. add comment
Snippet ID: | #1019595 |
Snippet name: | BWIntegralImage (size limit 8 megapixels, uses 4 byte per pixel) |
Eternal ID of this version: | #1019595/83 |
Text MD5: | 1b7a72aaea4b10244a4587f77165c1d0 |
Transpilation MD5: | 9720c55ad15b8e7c25bbe6b2ec3d2bd3 |
Author: | stefan |
Category: | javax / imaging |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2022-03-26 03:47:14 |
Source code size: | 7248 bytes / 253 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 698 / 1604 |
Version history: | 82 change(s) |
Referenced in: | [show references] |