Uses 108K of libraries. Click here for Pure Java version (10773L/76K).
1 | // complexity is number of assumed heights * number of widths |
2 | sclass MultiLevelRecognizer1 { |
3 | // how big do we think the prototype is in the whole image |
4 | // (percentage by height) |
5 | transient L<Double> assumedPrototypeHeightPercentages = ll(70.0, 70.0/sqrt(2), 35.0, 35.0/sqrt(2), 17.0); |
6 | |
7 | // widths to scale camera image to |
8 | transient L<Int> widths = ll(32, 64, 128); |
9 | |
10 | transient JTabbedPane tabs; // initialize if you want visualization |
11 | transient ImageSurface bestImageSurface; |
12 | transient JLabel bestLabel; |
13 | |
14 | transient BWIntegralImage baseImage; |
15 | transient BWImage prototypeImage; |
16 | transient new L<IBWIntegralImage> integralImages; |
17 | transient new L<Chain> chains; // one per assumed height |
18 | |
19 | // chain of recognizers for one assumed height |
20 | class Chain { |
21 | double assumedHeightPercentage; |
22 | new L<OneLevel> levels; // recognizers for each granularity |
23 | |
24 | *(double *assumedHeightPercentage) { make(); } |
25 | |
26 | void make { |
27 | for (int w : widths) { |
28 | IBWIntegralImage ii = scaledIBWIntegralImage(baseImage, w); |
29 | integralImages.add(ii); |
30 | OneLevel lvl = new(this, ii); |
31 | levels.add(lvl); |
32 | if (tabs != null && eq(w, last(widths))) { |
33 | lvl.is = jPixelatedZoomedImageSurface( |
34 | doubleRatio(baseImage.getWidth(), w), iBWIntegralImageToBWImage(ii)); |
35 | addTab(tabs, iround(assumedHeightPercentage) + ":" + w, northAndCenterWithMargins( |
36 | lvl.infoLabel = jcenteredlabel(), jFullCenterScroll(lvl.is))); |
37 | } |
38 | } |
39 | } |
40 | |
41 | Steppable makeSteppable() { |
42 | ret iteratorToSteppable(roundRobinCombinedIterator(lambdaMap steppableToIterator(levels))); |
43 | } |
44 | |
45 | Scored<Rect> bestResult() { |
46 | ret last(levels).scoredBestRescaled(); |
47 | } |
48 | } |
49 | |
50 | class OneLevel extends SteppableAndBest<Rect> { |
51 | Chain chain; |
52 | IBWIntegralImage ii; // scaled integral image |
53 | BWImage image; // scaled image |
54 | BWImage prototype; // scaled prototype |
55 | float minSimilarity = 0.5f; |
56 | |
57 | ImageSurface is; |
58 | JLabel infoLabel; |
59 | |
60 | // candidates are top-left corner of rect to try in our coordinates |
61 | L<Pt> candidatesQueue = syncLinkedList(); |
62 | new Set<Pt> candidatesTried; |
63 | Iterator<Pt> candidatesStream; |
64 | |
65 | *(Chain *chain, IBWIntegralImage *ii) { |
66 | image = iBWIntegralImageToBWImage(ii); |
67 | // get assumed height of prototype in scaled-down image |
68 | int ph = iround(ii.getHeight()*chain.assumedHeightPercentage/100.0); |
69 | // resize prototype |
70 | prototype = bwResizeToHeightSmooth(prototypeImage, ph); |
71 | /*addTab(tabs, "proto " + ii.getWidth(), jFullCenterScroll(jPixelatedZoomedImageSurface(4.0, prototype))); */ |
72 | candidatesStream = mapI rectTopLeftCorner(allSubRectsOfSizeIterator(prototype.getWidth(), prototype.getHeight(), |
73 | imageRect(image))); |
74 | } |
75 | |
76 | public bool step() { |
77 | Pt p = nextCandidate(); |
78 | if (p != null) ret true with tryCandidate(p); |
79 | false; |
80 | } |
81 | |
82 | Pt nextCandidate() { |
83 | try object Pt p = popFirst(candidatesQueue); |
84 | ret nextFromIterator(candidatesStream); |
85 | } |
86 | |
87 | void tryCandidate(Pt p) { |
88 | if (!candidatesTried.add(p)) ret; |
89 | |
90 | int x = p.x, y = p.y, wp = prototype.getWidth(), hp = prototype.getHeight(); |
91 | |
92 | float maxError = (1f-minSimilarity)*wp*hp; |
93 | float diff = bwImageSectionsSimilarity(image, prototype, x, y, maxError); |
94 | if (diff <= maxError) |
95 | best.put(new Rect(x, y, wp, hp), 1-diff/(wp*hp)); |
96 | } |
97 | |
98 | void showBest() { |
99 | setImageSurfaceSelection(is, best!); |
100 | setText(infoLabel, best); |
101 | } |
102 | |
103 | // best rect in original image coordinates |
104 | Rect bestRescaled() { |
105 | ret rescaleRect(best!, ii.getWidth(), ii.getHeight(), |
106 | baseImage.getWidth(), baseImage.getHeight()); |
107 | } |
108 | |
109 | Scored<Rect> scoredBestRescaled() { |
110 | ret scored(bestRescaled(), best.score); |
111 | } |
112 | } |
113 | |
114 | *() {} |
115 | *(File prototypeImage, File imgFile) { |
116 | this.prototypeImage = loadBWImage(prototypeImage); |
117 | this.baseImage = loadBWIntegralImage(imgFile); |
118 | } |
119 | |
120 | Scored<Rect> go() { |
121 | assertNotNull(+baseImage); |
122 | assertNotNull(+prototypeImage); |
123 | |
124 | if (tabs != null) |
125 | addTab(tabs, "Best", northAndCenterWithMargins( |
126 | bestLabel = jcenteredlabel(), |
127 | jFullCenterScroll(bestImageSurface = jImageSurface(bwIntegralImageToBWImage(baseImage))))); |
128 | |
129 | makeChains(); |
130 | |
131 | time "Process" { |
132 | print("Steps: " + stepAll_roundRobin(map(chains, c -> c.makeSteppable()))); |
133 | } |
134 | |
135 | showBest(); |
136 | ret bestResult(); |
137 | } |
138 | |
139 | void showBest { |
140 | for (Chain c : chains) |
141 | for (OneLevel l : c.levels) |
142 | l.showBest(); |
143 | setText(bestLabel, bestResult()); |
144 | setImageSurfaceSelection(bestImageSurface, bestResult()!); |
145 | } |
146 | |
147 | void makeChains { |
148 | for (double ah : assumedPrototypeHeightPercentages) |
149 | chains.add(new Chain(ah)); |
150 | } |
151 | |
152 | Scored<Rect> bestResult() { |
153 | ret bestScored(map(methodLambda0 bestResult, chains)); |
154 | } |
155 | } |
download show line numbers debug dex old transpilations
Travelled to 7 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv
No comments. add comment
Snippet ID: | #1027225 |
Snippet name: | MultiLevelRecognizer1 - finds a single prototype image |
Eternal ID of this version: | #1027225/32 |
Text MD5: | 2d327724a16b29fd1513a986e012be05 |
Transpilation MD5: | 3b267b00ce652cb4b0c5826b3fd604cc |
Author: | stefan |
Category: | javax / image recognition |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2020-02-26 15:16:33 |
Source code size: | 5053 bytes / 155 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 260 / 701 |
Version history: | 31 change(s) |
Referenced in: | [show references] |