Uses 911K of libraries. Click here for Pure Java version (15329L/86K).
1 | !7 |
2 | |
3 | cmodule ImageSegmenter > DynImageSurface { |
4 | // parameters |
5 | int blur; |
6 | bool distanceFromColor; |
7 | int dc_r, dc_g, dc_b; |
8 | float dc_gain = 5f, maxGain = 25f; |
9 | float contrastThreshold = 0.5f; |
10 | int gridSize = 2; |
11 | DoubleRange widthRange = new(0, 1); |
12 | DoubleRange heightRange = new(0, 1); |
13 | DoubleRange xRange = new(0, 1); |
14 | DoubleRange yRange = new(0, 1); |
15 | |
16 | transient S sliceID = "lgobeactljkewwtz"; |
17 | |
18 | // output |
19 | L<Rect> segments; |
20 | |
21 | transient BufferedImage blurredImage; |
22 | transient JLabel lblFound; |
23 | transient ReliableSingleThread rst = dm_rst(this, r segmentIt); |
24 | |
25 | visualize { |
26 | JSlider slider = main.onChange(jLiveValueSlider(dm_fieldLiveValue('contrastThreshold)), rst); |
27 | JSpinner spinner = main.onChange(dm_spinner gridSize(2, 10), rst); |
28 | JSpinner blurSpinner = main.onChange(dm_spinner blur(0, 10), rst); |
29 | |
30 | afterwards { |
31 | imageSurfaceOnHover(imageSurface, voidfunc(Pt p) { |
32 | RGB rgb = bufferedImage_getRGB(blurredImage, p); |
33 | setToolTip(imageSurface, rgb == null ? null : "Color: " + rgbToIntTriple(rgb)); |
34 | }); |
35 | updateLblFound(); rst.trigger(); |
36 | } |
37 | ret withCenteredLinesBelow(super.visualize(), |
38 | ll(jCenteredSection(" Preprocessing ", withSideMargin(20, jline( |
39 | withLabel("Blur:", blurSpinner), |
40 | main.onChange(dm_checkBox("Distance from color:", 'distanceFromColor), rst), |
41 | withLabel("R:", main.onChange(dm_spinner dc_r(0, 255), rst)), |
42 | withLabel("G:", main.onChange(dm_spinner dc_g(0, 255), rst)), |
43 | withLabel("B:", main.onChange(dm_spinner dc_b(0, 255), rst)), |
44 | withLabel("Gain:", main.onChange(jMinWidth(100, jLiveValueSliderZeroToX(maxGain, dm_fieldLiveValue('dc_gain))), rst)))))), |
45 | ll(jCenteredSection(" Segmenting ", withSideMargin(20, jline( |
46 | withLabel("Contrast Threshold:", jMinWidth(100, slider)), |
47 | withLabel("Grid size:", spinner), |
48 | jbutton("Segment", rst)))), |
49 | jCenteredSection(" Result ", withSideMargin(20, lblFound = jboldlabel(" "))), |
50 | jVerticalCenter(jPopDownButton_noText( |
51 | "Show segments", rThread showSegments, |
52 | "Publish result...", rThread publish, |
53 | "---", null, |
54 | "Screenshot (hiding OS)", rThread { setImage(dm_shootScreenHidingOS()); rst.trigger(); }, |
55 | ))), |
56 | ll( |
57 | withLabel("Width range:", main.onChange(doubleRangeLiveValueSlider(dm_fieldLiveValue('widthRange)), rst)), |
58 | withLabel("Height range:", main.onChange(doubleRangeLiveValueSlider(dm_fieldLiveValue('heightRange)), rst))), |
59 | ll( |
60 | withLabel("X position:", main.onChange(doubleRangeLiveValueSlider(dm_fieldLiveValue('xRange)), rst)), |
61 | withLabel("Y position:", main.onChange(doubleRangeLiveValueSlider(dm_fieldLiveValue('yRange)), rst)))); |
62 | } |
63 | |
64 | start { |
65 | if (!hasImage()) setImage(whiteImage(100, 100)); |
66 | dm_vmBus_onMessage('newClipboardContents, voidfunc(O o) { |
67 | if (o cast BufferedImage) thread { setImage(o); rst.trigger(); } |
68 | }); |
69 | } |
70 | |
71 | void segmentIt enter { |
72 | if (!hasImage()) ret; |
73 | int w = imageWidth(), h = imageHeight(); |
74 | |
75 | BufferedImage image = getImage(); |
76 | BufferedImage imageToDraw = null; |
77 | if (blur != 0) |
78 | image = imageToDraw = new BoxBlurFilter(blur).filter(image, null); |
79 | blurredImage = image; |
80 | |
81 | new AutoSegmenter as; |
82 | as.g = gridSize; |
83 | as.contrastThreshold = contrastThreshold; |
84 | BWImage bw; |
85 | if (distanceFromColor) { |
86 | bw = img_distanceFromColor_withGain(image, rgbFromInts(dc_r, dc_g, dc_b), dc_gain); |
87 | imageToDraw = bw.getBufferedImage(); |
88 | } else |
89 | bw = BWImage(image); |
90 | L<Rect> segments = as.go(bw); |
91 | IntRange wr = doubleToIntRange_endPlus1(w, widthRange); |
92 | IntRange hr = doubleToIntRange_endPlus1(h, heightRange); |
93 | IntRange xr = doubleToIntRange_endPlus1(w, xRange); |
94 | IntRange yr = doubleToIntRange_endPlus1(h, yRange); |
95 | printVars_str(+wr, +hr, +xr, +yr); |
96 | segments = filterRectsByWidthRange(segments, wr); |
97 | segments = filterRectsByHeightRange(segments, hr); |
98 | segments = filterRectsByCenterXRange(segments, xr); |
99 | segments = filterRectsByCenterYRange(segments, yr); |
100 | setField(+segments); |
101 | updateLblFound(); |
102 | imageSurface.imageToDraw = imageToDraw; |
103 | overlaySelectionsOnImageSurface(imageSurface, segments); |
104 | } |
105 | |
106 | void showSegments { |
107 | L<Rect> segments = this.segments; |
108 | showImage_centered(n2(segments, "segment") + " found", |
109 | mergeBufferedImagesVertically(map(segments, r -> clipBufferedImage(getImage(), r)))); |
110 | } |
111 | |
112 | void updateLblFound { |
113 | setText(lblFound, nSegments(segments) + " found"); |
114 | } |
115 | |
116 | void publish enter { |
117 | SS map = parameters(); |
118 | BufferedImage image = getImage(); |
119 | JTextField tfDesc = jtextfield(), tfSuccess = jtextfield(); |
120 | |
121 | showFormTitled("Publish image segmentation result", |
122 | "Image", jImageSurface(scaleImageToWidth(image, 200)), |
123 | "Task description", tfDesc, |
124 | "How successful was the result?", tfSuccess, |
125 | "# segments found", l_str(segments), |
126 | "Parameters", jMinHeight(200, disableTextArea(jWordWrapTextArea(pnlToString(mapMinus(map, "segments"))))), |
127 | "NOTE:", jMultiLineLabel("By clicking 'publish', you PUBLISH this image (fair use/public domain)."), |
128 | "", jThreadedButton("Publish", r { |
129 | S desc = gtt(tfDesc), success = gtt(tfSuccess); |
130 | if (empty(desc)) ret with infoBox("Need a description"); |
131 | temp tempInfoBox_noHide("Uploading..."); |
132 | S imageURL = uploadToImageServer(desc, image); |
133 | map.put("Successful?", success); |
134 | map.put("Input image", imageURL); |
135 | new L<Map> toPost; |
136 | S name = agiBlue_createUnusedNumberedPage(sliceID, desc + " #"); |
137 | for (S key, value : map) |
138 | toPost.add(litmap(q := name, +key, +value)); |
139 | agiBot_postMulti(keyPairForProgram(), toPost, slice := sliceID); |
140 | infoBox("Segmentation result uploaded!"); |
141 | openURLInBrowser(agiBlue_linkForPhrase(name, slice := sliceID)); |
142 | disposeWindow(heldButton()); |
143 | }) |
144 | ); |
145 | } |
146 | |
147 | Set<S> parameterFields() { ret nonStaticNonTransientFields_withoutSuperclasses(this); } |
148 | |
149 | SS parameters() { |
150 | ret mapToValues_treeMap(parameterFields(), field -> struct(get(module(), field))); |
151 | } |
152 | } |
Began life as a copy of #1024537
download show line numbers debug dex old transpilations
Travelled to 6 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1024568 |
Snippet name: | Image Segmenter v3 [with upload] |
Eternal ID of this version: | #1024568/17 |
Text MD5: | 5ca03d3a3236bce0487ab59b89013254 |
Transpilation MD5: | 2677f0170b595ad830ea6f2cb25d3539 |
Author: | stefan |
Category: | javax / image analysis |
Type: | JavaX source code (Dynamic Module) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2019-08-18 22:09:30 |
Source code size: | 6346 bytes / 152 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 303 / 807 |
Version history: | 16 change(s) |
Referenced in: | [show references] |