lost-sia 1.3.0 → 2.0.0-alpha0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +0 -0
  3. package/package.json +60 -47
  4. package/src/AnnoExampleViewer.jsx +57 -0
  5. package/src/AnnoLabelInput.jsx +99 -0
  6. package/src/AnnoToolBar.jsx +132 -0
  7. package/src/Annotation/AnnoBar.jsx +148 -0
  8. package/src/Annotation/Annotation.jsx +358 -0
  9. package/src/Annotation/Annotation.scss +47 -0
  10. package/src/Annotation/BBox.jsx +291 -0
  11. package/src/Annotation/Edge.jsx +82 -0
  12. package/src/Annotation/InfSelectionArea.jsx +71 -0
  13. package/src/Annotation/Line.jsx +60 -0
  14. package/src/Annotation/Node.jsx +278 -0
  15. package/src/Annotation/Point.jsx +196 -0
  16. package/src/Annotation/Polygon.jsx +361 -0
  17. package/src/Canvas.jsx +1839 -0
  18. package/src/ImgBar.jsx +123 -0
  19. package/src/InfoBoxes/AnnoDetails.jsx +166 -0
  20. package/src/InfoBoxes/AnnoStats.jsx +104 -0
  21. package/src/InfoBoxes/InfoBox.jsx +78 -0
  22. package/src/InfoBoxes/InfoBoxArea.jsx +155 -0
  23. package/src/InfoBoxes/LabelInfo.jsx +95 -0
  24. package/src/LabelInput.jsx +224 -0
  25. package/src/Prompt.jsx +46 -0
  26. package/src/SIA.scss +10 -0
  27. package/src/SIAFilterButton.jsx +178 -0
  28. package/src/SIASettingButton.jsx +122 -0
  29. package/src/Sia.jsx +485 -0
  30. package/src/SiaPopup.jsx +10 -0
  31. package/src/ToolBar.jsx +399 -0
  32. package/src/Toolbar.css +13 -0
  33. package/src/ToolbarItem.jsx +25 -0
  34. package/src/filterTools.js +3 -0
  35. package/src/index.js +17 -0
  36. package/src/siaDummyData.js +265 -0
  37. package/src/test.js +7 -0
  38. package/src/types/annoStatus.js +4 -0
  39. package/src/types/canvasActions.js +57 -0
  40. package/src/types/cursorstyles.js +3 -0
  41. package/src/types/modes.js +8 -0
  42. package/src/types/notificationType.js +4 -0
  43. package/src/types/toolbarEvents.js +33 -0
  44. package/src/types/tools.js +11 -0
  45. package/src/utils/annoConversion.js +115 -0
  46. package/src/utils/colorlut.js +67 -0
  47. package/src/utils/constraints.js +75 -0
  48. package/src/utils/hist.js +67 -0
  49. package/src/utils/keyActions.js +107 -0
  50. package/src/utils/mouse.js +14 -0
  51. package/src/utils/siaIcons.jsx +95 -0
  52. package/src/utils/transform.js +318 -0
  53. package/src/utils/uiConfig.js +57 -0
  54. package/src/utils/windowViewport.js +35 -0
  55. package/CHANGELOG.md +0 -169
  56. package/dist/index.css +0 -24823
  57. package/dist/index.es.js +0 -10482
  58. package/dist/index.es.js.map +0 -1
  59. package/dist/index.js +0 -10497
  60. package/dist/index.js.map +0 -1
@@ -0,0 +1,399 @@
1
+ import React, { useState, useEffect, useRef } from 'react'
2
+ import { Button, Card } from 'semantic-ui-react'
3
+ import { faArrowLeft, faArrowRight, faBan, faCheck, faMaximize, faQuestion, faSave, faSearch, faTag, faTrash, faVectorSquare } from '@fortawesome/free-solid-svg-icons'
4
+ import { faPaperPlane } from '@fortawesome/free-regular-svg-icons'
5
+ import SIASettingButton from './SIASettingButton'
6
+ import SIAFilterButton from './SIAFilterButton'
7
+ import Prompt from './Prompt'
8
+ import './Toolbar.css'
9
+
10
+ import * as TOOLS from './types/tools'
11
+ import * as siaIcons from './utils/siaIcons'
12
+ import * as tbe from './types/toolbarEvents'
13
+ import { CSidebar, CSidebarNav } from '@coreui/react'
14
+ import ToolbarItem from './ToolbarItem'
15
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
16
+
17
+ const ToolBar = (props) => {
18
+ const [position, setPosition] = useState({
19
+ left: 0,
20
+ top: 5,
21
+ width: 40,
22
+ })
23
+ const [showFinishPrompt, setShowFinishPrompt] = useState(false)
24
+ const [showHelp, setShowHelp] = useState(false)
25
+
26
+ const toolBarGroup = useRef(null)
27
+
28
+ const toolbarItemStyle = { background: '#1b1c1d' }
29
+
30
+ // if (prevState.fullscreenMode !== this.state.fullscreenMode){
31
+ // this.props.siaSetFullscreen(this.state.fullscreenMode)
32
+ // }
33
+
34
+ useEffect(() => {
35
+ calcPosition()
36
+ }, [props.layoutUpdate, props.svg])
37
+
38
+ const onClick = (e, tool) => {
39
+ triggerToolBarEvent(tbe.TOOL_SELECTED, tool)
40
+ }
41
+
42
+ const calcPosition = () => {
43
+ if (!props.enabled) return
44
+ const tb = toolBarGroup.current.getBoundingClientRect()
45
+ if (tb) {
46
+ if (props.svg) {
47
+ let toolBarTop = props.svg.top + props.svg.height / 6
48
+ setPosition({
49
+ ...position,
50
+ left: props.svg.left - 55,
51
+ top: toolBarTop,
52
+ })
53
+ }
54
+ }
55
+ }
56
+
57
+ const getNextImg = () => {
58
+ // this.props.siaGetNextImage(this.props.imageMeta.id)
59
+ triggerToolBarEvent(tbe.GET_NEXT_IMAGE)
60
+ }
61
+
62
+ const getPrevImg = () => {
63
+ // this.props.siaGetPrevImage(this.props.imageMeta.id)
64
+ triggerToolBarEvent(tbe.GET_PREV_IMAGE)
65
+ }
66
+
67
+ const setFinished = () => {
68
+ // this.props.siaSetTaskFinished()
69
+ triggerToolBarEvent(tbe.TASK_FINISHED)
70
+ }
71
+
72
+ const toggleFinishPrompt = () => {
73
+ setShowFinishPrompt(!showFinishPrompt)
74
+ }
75
+
76
+ const toggleFullscreen = () => {
77
+ // this.setState({
78
+ // fullscreenMode: !this.state.fullscreenMode
79
+ // })
80
+ triggerToolBarEvent(tbe.SET_FULLSCREEN)
81
+ }
82
+
83
+ const toggleImgLabelInput = () => {
84
+ // this.props.siaShowImgLabelInput(!this.props.imgLabelInput.show)
85
+ triggerToolBarEvent(tbe.SHOW_IMAGE_LABEL_INPUT)
86
+ }
87
+
88
+ const toggleJunk = () => {
89
+ // this.props.siaImgIsJunk(!this.props.isJunk)
90
+ triggerToolBarEvent(tbe.IMG_IS_JUNK)
91
+ }
92
+
93
+ const toggleHelp = () => {
94
+ setShowHelp(!showHelp)
95
+ }
96
+
97
+ const handleOnDeleteAllAnnos = () => {
98
+ triggerToolBarEvent(tbe.DELETE_ALL_ANNOS)
99
+ }
100
+
101
+ const handleSave = () => {
102
+ triggerToolBarEvent(tbe.SAVE)
103
+ }
104
+
105
+ const triggerToolBarEvent = (event, data) => {
106
+ if (props.onToolBarEvent) {
107
+ props.onToolBarEvent(event, data)
108
+ }
109
+ }
110
+
111
+ const renderToolButtons = () => {
112
+ if (!props.canvasConfig) return null
113
+ if (!props.enabled.toolSelection) return null
114
+ if (!props.canvasConfig.annos.actions.draw) return null
115
+ let btns = []
116
+ if (props.canvasConfig.tools.point) {
117
+ btns.push(
118
+ <ToolbarItem
119
+ active={props.active.selectedTool === TOOLS.POINT}
120
+ onClick={(e) => onClick(e, TOOLS.POINT)}
121
+ siaIcon={siaIcons.pointIcon()}
122
+ />
123
+ )
124
+ }
125
+ if (props.canvasConfig.tools.line) {
126
+ btns.push(
127
+ <ToolbarItem
128
+ active={props.active.selectedTool === TOOLS.LINE}
129
+ onClick={(e) => onClick(e, TOOLS.LINE)}
130
+ siaIcon={siaIcons.lineIcon()}
131
+ />
132
+ )
133
+ }
134
+ if (props.canvasConfig.tools.bbox) {
135
+ btns.push(
136
+ <ToolbarItem
137
+ active={props.active.selectedTool === TOOLS.BBOX}
138
+ onClick={(e) => onClick(e, TOOLS.BBOX)}
139
+ faIcon={faVectorSquare}
140
+ />
141
+ )
142
+ }
143
+ if (props.canvasConfig.tools.polygon) {
144
+ btns.push(
145
+ <ToolbarItem
146
+ active={props.active.selectedTool === TOOLS.POLYGON}
147
+ onClick={(e) => onClick(e, TOOLS.POLYGON)}
148
+ siaIcon={siaIcons.polygonIcon()}
149
+ />
150
+ )
151
+ }
152
+ return btns
153
+ }
154
+
155
+ const renderFinishPrompt = () => {
156
+ return (
157
+ <Prompt active={showFinishPrompt}
158
+ header={<div>
159
+ <FontAwesomeIcon icon={faPaperPlane} />&nbsp;
160
+ Do you wish to FINISH this SIA Task?
161
+ </div>}
162
+ content={<div>
163
+ <Button basic color="green" inverted onClick={() => setFinished()}>
164
+ <FontAwesomeIcon icon={faCheck} /> &nbsp;
165
+ Yes
166
+ </Button>
167
+ <Button basic color="red" inverted onClick={() => toggleFinishPrompt()}>
168
+ <FontAwesomeIcon icon={faBan} /> &nbsp;
169
+ No
170
+ </Button>
171
+ </div>}
172
+ />
173
+ )
174
+ }
175
+ /**
176
+ * Render next and prev image buttons
177
+ *
178
+ */
179
+ const renderNavigation = () => {
180
+ let btns = []
181
+ if (!props.enabled.nextPrev) return null
182
+ if (props.imageMeta) {
183
+ if (props.imageMeta.isLast) {
184
+ btns.push(
185
+ <>
186
+ <ToolbarItem
187
+ onClick={() => toggleFinishPrompt()}
188
+ faIcon={faPaperPlane}
189
+ />
190
+ {renderFinishPrompt()}
191
+ </>
192
+ )
193
+ } else {
194
+ btns.push(
195
+ <ToolbarItem
196
+ onClick={() => getNextImg()}
197
+ faIcon={faArrowRight}
198
+ />
199
+ )
200
+ }
201
+ btns.push(
202
+ <ToolbarItem
203
+ disabled={props.imageMeta.isFirst}
204
+ onClick={() => getPrevImg()}
205
+ faIcon={faArrowLeft}
206
+ />
207
+ )
208
+ }
209
+ return btns
210
+ }
211
+
212
+ const renderJunkButton = () => {
213
+ if (!props.enabled.junk) return null
214
+
215
+ return (
216
+ <ToolbarItem
217
+ active={props.active.isJunk}
218
+ onClick={() => toggleJunk()}
219
+ faIcon={faBan}
220
+ />
221
+ )
222
+ }
223
+
224
+ const renderDeleteAllAnnosButton = () => {
225
+ if (!props.enabled.deleteAll) return null
226
+ return (
227
+ <ToolbarItem
228
+ onClick={() => handleOnDeleteAllAnnos()}
229
+ faIcon={faTrash}
230
+ />
231
+ )
232
+ }
233
+
234
+ const renderSaveButton = () => {
235
+ if (!props.enabled.save) return null
236
+ return (
237
+ <ToolbarItem
238
+ onClick={() => handleSave()}
239
+ faIcon={faSave}
240
+ />
241
+ )
242
+ }
243
+
244
+ const renderHelpButton = () => {
245
+ if (!props.enabled.help) return null
246
+ return (
247
+ <>
248
+ <ToolbarItem
249
+ onClick={() => toggleHelp()}
250
+ faIcon={faQuestion}
251
+ />
252
+ <Prompt
253
+ active={showHelp}
254
+ onClick={() => toggleHelp()}
255
+ content={
256
+ <div>
257
+ <Card.Group>
258
+ <Card>
259
+ <Card.Content header='How to draw?' />
260
+ <Card.Content description='1.) Select a Tool in the toolbar 2.) Draw with RIGHT CLICK on Canvas' />
261
+ </Card>
262
+ <Card>
263
+ <Card.Content header='How to delete an annotation?' />
264
+ <Card.Content description='1.) Select an annotation with LEFT CLICK 2.) Press DELETE or BACKSPACE' />
265
+ </Card>
266
+ <Card>
267
+ <Card.Content header='How to assign a label?' />
268
+ <Card.Content description='1.) Select an annotation with LEFT CLICK 2.) Hit ENTER 3.) Type into the input field 4.) Hit ENTER to confirm 5.) Hit ESCAPE to close the input field' />
269
+ </Card>
270
+ <Card>
271
+ <Card.Content header='Undo/ Redo' />
272
+ <Card.Content description='Undo: Hit STRG + Z' />
273
+ <Card.Content description='Redo: Hit STRG + R' />
274
+ </Card>
275
+ <Card>
276
+ <Card.Content header='Add a node to Line/Polygon' />
277
+ <Card.Content description='Hit STRG + Click left on the line' />
278
+ </Card>
279
+ <Card>
280
+ <Card.Content header='Remove a node from Line/Polygon in create mode' />
281
+ <Card.Content description='Press DELETE or BACKSPACE' />
282
+ </Card>
283
+ <Card>
284
+ <Card.Content header='Edit Line/Polygon' />
285
+ <Card.Content description='1.) Click on the Annotation you want to edit.' />
286
+ <Card.Content description='2.) Press "e". New nodes can now be added using right click' />
287
+ </Card>
288
+ <Card>
289
+ <Card.Content header='Zoom/ Move Canvas' />
290
+ <Card.Content description='Zoom: Use MOUSE WHEEL to zoom in/out' />
291
+ <Card.Content description='Move: Hold MOUSE WHEEL and move mouse. Or Use W/A/S/D keys to move camera up/left/down/right' />
292
+ </Card>
293
+ <Card>
294
+ <Card.Content header='TAB navigation' />
295
+ <Card.Content description='You can traverse all visible annotation by hitting TAB.' />
296
+ </Card>
297
+ <Card>
298
+ <Card.Content header='Next/Prev image navigation' />
299
+ <Card.Content description='Get next image by hitting ARROW_RIGHT key. Get previous image by hitting ARROW_LEFT key.' />
300
+ </Card>
301
+ <Card>
302
+ <Card.Content header='Copy and Paste annotations' />
303
+ <Card.Content description='Copy: 1.) Select annotation 2.) Hit STRG + C' />
304
+ <Card.Content description='Paste: STRG + V' />
305
+ </Card>
306
+ <Card>
307
+ <Card.Content header='Mark image as junk' />
308
+ <Card.Content description='1.) Press J key' />
309
+ </Card>
310
+ <Card>
311
+ <Card.Content header='Assign a comment to a 2D annoation' />
312
+ <Card.Content description='1.) Select annotation 2.) Hit C key' />
313
+ </Card>
314
+ </Card.Group>
315
+ </div>}
316
+ />
317
+ </>
318
+ )
319
+ }
320
+
321
+ const renderImgLabelInput = () => {
322
+ if (!props.enabled.imgLabel) return null
323
+ if (props.canvasConfig.img.actions.label) {
324
+ return <ToolbarItem
325
+ // active={this.props.imgLabelInput.show}
326
+ onClick={() => toggleImgLabelInput()}
327
+ faIcon={faTag}
328
+ />
329
+ }
330
+ }
331
+
332
+ const renderImageSearch = () => {
333
+ if (!props.enabled.imgSearch) return null
334
+
335
+ return <ToolbarItem faIcon={faSearch} onClick={() => {
336
+ if (props.onImgageSearchClicked) return props.onImgageSearchClicked()
337
+ }} />
338
+ }
339
+
340
+ const renderFullscreenBtn = () => {
341
+ if (!props.enabled.fullscreen) return null
342
+ return (
343
+ <ToolbarItem
344
+ active={props.active.fullscreen}
345
+ onClick={() => toggleFullscreen()}
346
+ faIcon={faMaximize}
347
+ />
348
+ )
349
+ }
350
+
351
+ const renderSettingBtn = () => {
352
+ if (!props.enabled.settings) return null
353
+
354
+ return <SIASettingButton
355
+ enabled={props.enabled.settings}
356
+ uiConfig={props.uiConfig}
357
+ onSettingEvent={(e, data) => triggerToolBarEvent(e, data)}
358
+ toolbarItemStyle={toolbarItemStyle}
359
+ />
360
+ }
361
+
362
+ const renderFilterBtn = () => {
363
+ if (!props.enabled.filter) return null
364
+ if (!props.filter) return null
365
+ return <SIAFilterButton
366
+ enabled={props.enabled.filter}
367
+ onFilterEvent={(e, data) => triggerToolBarEvent(e, data)}
368
+ filter={props.filter}
369
+ imageMeta={props.imageMeta}
370
+ toolbarItemStyle={toolbarItemStyle}
371
+ />
372
+ }
373
+
374
+ if (!props.enabled) return null
375
+
376
+ return (
377
+ <div
378
+ ref={toolBarGroup}
379
+ style={{ position: 'fixed', top: position.top, left: position.left }}>
380
+ <CSidebar narrow className="sia-toolbar">
381
+ <CSidebarNav>
382
+ {renderSettingBtn()}
383
+ {renderFilterBtn()}
384
+ {renderSaveButton()}
385
+ {renderImgLabelInput()}
386
+ {renderImageSearch()}
387
+ {renderNavigation()}
388
+ {renderToolButtons()}
389
+ {renderJunkButton()}
390
+ {renderDeleteAllAnnosButton()}
391
+ {renderFullscreenBtn()}
392
+ {renderHelpButton()}
393
+ </CSidebarNav>
394
+ </CSidebar>
395
+ </div >
396
+ )
397
+ }
398
+
399
+ export default ToolBar
@@ -0,0 +1,13 @@
1
+ .sia-toolbar {
2
+ border-radius: 0 5px 5px 0;
3
+ background: #1b1c1d;
4
+ width: 55px;
5
+ cursor: pointer;
6
+ padding-bottom: 0;
7
+ }
8
+
9
+ .sia-toolbar-item {
10
+ padding: 13px 0px;
11
+ display: flex;
12
+ justify-content: center;
13
+ }
@@ -0,0 +1,25 @@
1
+ import { CNavItem } from "@coreui/react"
2
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
3
+ import './Toolbar.css'
4
+
5
+ const ToolbarItem = ({ active = false, disabled = false, faIcon, siaIcon, onClick }) => {
6
+
7
+ let color = 'white'
8
+ if (active) color = 'red'
9
+ if (disabled) color = 'grey'
10
+
11
+ return (<CNavItem>
12
+ <div className="sia-toolbar-item"
13
+ onClick={() => {
14
+ if (!disabled && onClick) onClick()
15
+ }}
16
+ >
17
+ {faIcon && <FontAwesomeIcon icon={faIcon} size='lg' color={color} />}
18
+ {siaIcon && <span style={{ color: color }}>
19
+ {siaIcon}
20
+ </span>}
21
+ </div>
22
+ </CNavItem>)
23
+ }
24
+
25
+ export default ToolbarItem
@@ -0,0 +1,3 @@
1
+ export function active(filter){
2
+ return filter.clahe.active || filter.rotate.active
3
+ }
package/src/index.js ADDED
@@ -0,0 +1,17 @@
1
+
2
+ import 'semantic-ui-css/semantic.min.css'
3
+ // import { default as Canvas } from './Canvas'
4
+ // import { default as Toolbar } from './ToolBar'
5
+ export { default as Canvas } from './Canvas'
6
+
7
+ // export { Canvas }
8
+ // export { Toolbar }
9
+
10
+ export { default as Sia } from './Sia'
11
+ export { default as dummyData } from './siaDummyData'
12
+ export { default as transform } from './utils/transform'
13
+ export { default as annoConversion } from './utils/annoConversion'
14
+ export { default as canvasActions } from './types/canvasActions'
15
+ export { default as toolbarEvents } from './types/toolbarEvents'
16
+ export { default as tools } from './types/tools'
17
+