Libraryless. Click here for Pure Java version (6671L/39K).
1 | // U for stands for the "Ultra-Fast Recognition" family of recognizers |
2 | sclass URecognizer { |
3 | IIntegralImage image; |
4 | |
5 | *() {} |
6 | *(IIntegralImage *image) {} |
7 | *(BufferedImage image) { |
8 | this.image = IntegralImage(image); |
9 | } |
10 | |
11 | // returns 0, 1 or 2 |
12 | int posterizeToInt(double x) { |
13 | ret ifloor(clampZeroToOne(x)*3); |
14 | } |
15 | |
16 | // returns 0, .5 or 1 |
17 | double posterizeInPlace(double x) { |
18 | ret posterizeToInt(x)*.5; |
19 | } |
20 | |
21 | class Cell { |
22 | // Which part of the image we are looking at (x/y) |
23 | // dimension 0 = x, dimension 1 = y |
24 | DoubleRange[] clip = new[2]; |
25 | |
26 | // color transformations in place |
27 | DoubleRange[] colorClips = new[3]; |
28 | |
29 | Cell copy() { |
30 | ret copyTo(new Cell); |
31 | } |
32 | |
33 | Cell copyTo(Cell c) { |
34 | arrayCopy(clip, c.clip); |
35 | arrayCopy(colorClips, c.colorClips); |
36 | ret c; |
37 | } |
38 | |
39 | DoubleRect rawDoubleRect() { |
40 | ret doubleRectFromRanges(clip[0], clip[1]); |
41 | } |
42 | |
43 | Rect rectInImage() { |
44 | ret rectMinSize(1, 1, toRect_floor(doubleRectFromRanges(clip[0], clip[1]))); |
45 | } |
46 | |
47 | // uses full pixels to match the pixel queries |
48 | double screenArea() { ret rectArea(rectInImage()); } |
49 | |
50 | // get color of cell |
51 | |
52 | double color(int channel) { |
53 | double color = ii_averageBrightnessOfArea(image, rectInImage(), channel); |
54 | ret transformBetweenDoubleRanges(color, colorClips[channel], zeroToOne()); |
55 | } |
56 | |
57 | // unposterized color of all 3 channels |
58 | double[] colors() { |
59 | double[] c = new[3]; |
60 | for i to 3: |
61 | c[i] = color(i); |
62 | ret c; |
63 | } |
64 | |
65 | RGB rgb aka averageColor() { |
66 | ret RGB(colors()); |
67 | } |
68 | |
69 | toString { |
70 | ret rectInImage() + ", color: " + map(asList(colors()), x -> formatDoubleX(x, 4)); |
71 | } |
72 | |
73 | int posterizedIntColor(int channel) { |
74 | ret posterizeToInt(color(channel)); |
75 | } |
76 | |
77 | // get sub-cells |
78 | |
79 | Cell[] cellArray(int n) { |
80 | ret new Cell[n]; |
81 | } |
82 | |
83 | Cell[] split(int dimension, int n default 3) { |
84 | Cell[] cells = cellArray(n); |
85 | for i to n: cells[i] = slice(dimension, doubleRatio(i, n), doubleRatio(i+1, n)); |
86 | ret cells; |
87 | } |
88 | |
89 | Cell slice(int dimension, double a, double b) { |
90 | Cell c = copy(); |
91 | c.clip[dimension] = transformBetweenDoubleRanges(DoubleRange(a, b), zeroToOne(), clip[dimension]); |
92 | ret c; |
93 | } |
94 | |
95 | // rect is within 0 to 1 in both dimensions |
96 | Cell clip(DoubleRect r) { |
97 | ret slice(0, r.x1(), r.x2()).slice(1, r.y1(), r.y2()); |
98 | } |
99 | |
100 | // index = 0 to 2 |
101 | Cell third(int dimension, int index) { |
102 | ret slice(dimension, index/3.0, (index+1)/3.0); |
103 | } |
104 | |
105 | // convert to B/W |
106 | |
107 | BWCell channel(int channel) { |
108 | new BWCell c; |
109 | copyTo(c); |
110 | c.colorToBW = rgb -> rgb[channel]; |
111 | ret c; |
112 | } |
113 | |
114 | BWCell brightness() { |
115 | new BWCell c; |
116 | copyTo(c); |
117 | ret c; |
118 | } |
119 | |
120 | double averageBrightness aka get() { |
121 | ret brightness().color(); |
122 | } |
123 | |
124 | double getWidth() { ret clip[0].length(); } |
125 | double getHeight() { ret clip[1].length(); } |
126 | |
127 | double pixelSum() { |
128 | ret image.rectSum(rectInImage()); |
129 | } |
130 | } |
131 | |
132 | class BWCell extends Cell { |
133 | IF1<double[], Double> colorToBW = rgb -> (rgb[0]+rgb[1]+rgb[2])/3; |
134 | |
135 | double color() { |
136 | ret colorToBW.get(colors()); |
137 | } |
138 | |
139 | BWCell copy() { |
140 | new BWCell c; |
141 | copyTo(c); |
142 | ret c; |
143 | } |
144 | |
145 | void copyTo(BWCell c) { |
146 | super.copyTo(c); |
147 | c.colorToBW = colorToBW; |
148 | } |
149 | |
150 | toString { |
151 | ret rectInImage() + ", Color: " + formatDoubleX(color(), 4); |
152 | } |
153 | |
154 | // lift methods |
155 | |
156 | BWCell[] cellArray(int n) { |
157 | ret new BWCell[n]; |
158 | } |
159 | |
160 | BWCell slice(int dimension, double a, double b) { |
161 | ret (BWCell) super.slice(dimension, a, b); |
162 | } |
163 | |
164 | BWCell[] split(int dimension) { |
165 | ret (BWCell[]) super.split(dimension); |
166 | } |
167 | |
168 | BWCell third(int dimension, int index) { |
169 | ret (BWCell) super.third(dimension, index); |
170 | } |
171 | } |
172 | |
173 | // make the root cell |
174 | Cell rootCell aka cell() { |
175 | new Cell c; |
176 | c.clip[0] = doubleRange(0, image.getWidth()); |
177 | c.clip[1] = doubleRange(0, image.getHeight()); |
178 | for i to 3: c.colorClips[i] = doubleRange(0, 255); |
179 | ret c; |
180 | } |
181 | |
182 | int outlierPosition(BWCell[] cells) { |
183 | double a = cells[0].color(); |
184 | double b = cells[1].color(); |
185 | double c = cells[2].color(); |
186 | double ab = abs(a-b), bc = abs(b-c), ac = abs(a-c); |
187 | if (bc < min(ab, ac)) ret 0; // b and c close together |
188 | if (ac < min(ab, bc)) ret 1; // a and c close together |
189 | if (ab < min(ac, bc)) ret 2; // a and b close together |
190 | ret -1; // unknown |
191 | } |
192 | } |
download show line numbers debug dex old transpilations
Travelled to 4 computer(s): bhatertpkbcr, ekrmjmnbrukm, mqqgnosmbjvj, pyentgdyhuwx
No comments. add comment
Snippet ID: | #1031930 |
Snippet name: | URecognizer [main image recognizer utility] |
Eternal ID of this version: | #1031930/54 |
Text MD5: | a772ba9c9f6823c7eb649dec1a86053b |
Transpilation MD5: | bdcbf9e3fd515f6372a5fd9159e390c6 |
Author: | stefan |
Category: | javax / image recognition |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2021-09-10 17:01:27 |
Source code size: | 4789 bytes / 192 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 296 / 621 |
Version history: | 53 change(s) |
Referenced in: | [show references] |