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: | 468 / 999 |
| Version history: | 16 change(s) |
| Referenced in: | [show references] |