@@ -4,8 +4,44 @@ import React, { useState, useEffect, useMemo, useRef } from "react"
4
4
import { colorInts } from "../colors"
5
5
import { useDebounce } from "react-use"
6
6
import loadImage from "./load-image"
7
+ import autoseg from "autoseg/webworker"
7
8
8
- import MMGC_INIT from "mmgc1-cpp"
9
+ function convertToUDTRegions ( regions ) {
10
+ return regions
11
+ . map ( ( r ) => {
12
+ switch ( r . type ) {
13
+ case "point" : {
14
+ return {
15
+ regionType : "point" ,
16
+ classification : r . cls ,
17
+ x : r . x ,
18
+ y : r . y ,
19
+ }
20
+ }
21
+ case "polygon" : {
22
+ return {
23
+ regionType : "polygon" ,
24
+ classification : r . cls ,
25
+ points : r . points . map ( ( [ x , y ] ) => ( { x, y } ) ) ,
26
+ }
27
+ }
28
+ case "box" : {
29
+ return {
30
+ regionType : "bounding-box" ,
31
+ classification : r . cls ,
32
+ centerX : r . x + r . w / 2 ,
33
+ centerY : r . y + r . h / 2 ,
34
+ width : r . w ,
35
+ height : r . h ,
36
+ }
37
+ }
38
+ default : {
39
+ return null
40
+ }
41
+ }
42
+ } )
43
+ . filter ( Boolean )
44
+ }
9
45
10
46
export const ImageMask = ( {
11
47
regions,
@@ -16,18 +52,20 @@ export const ImageMask = ({
16
52
hide = false ,
17
53
autoSegmentationOptions = { type : "simple" } ,
18
54
} ) => {
19
- if ( ! window . mmgc ) window . mmgc = MMGC_INIT ( )
20
- const mmgc = window . mmgc
55
+ // if (!window.mmgc) window.mmgc = MMGC_INIT()
56
+ // const mmgc = window.mmgc
21
57
const [ canvasRef , setCanvasRef ] = useState ( null )
22
58
23
- const superPixelsGenerated = useRef ( false )
24
59
const [ sampleImageData , setSampleImageData ] = useState ( )
25
60
26
61
useEffect ( ( ) => {
27
62
if ( ! imageSrc ) return
28
63
29
64
loadImage ( imageSrc ) . then ( ( imageData ) => {
30
- superPixelsGenerated . current = false
65
+ autoseg . setConfig ( {
66
+ classNames : regionClsList ,
67
+ } )
68
+ autoseg . loadImage ( imageData )
31
69
setSampleImageData ( imageData )
32
70
} )
33
71
} , [ imageSrc ] )
@@ -38,103 +76,14 @@ export const ImageMask = ({
38
76
if ( ! canvasRef ) return
39
77
if ( ! sampleImageData ) return
40
78
if ( regions . filter ( ( cp ) => cp . cls ) . length < 2 ) return
41
- if ( ! mmgc . setImageSize ) return
42
- const context = canvasRef . getContext ( "2d" )
43
-
44
- if ( ! superPixelsGenerated . current ) {
45
- superPixelsGenerated . current = "processing"
46
- mmgc . setSimpleMode ( autoSegmentationOptions . type === "simple" )
47
- mmgc . setMaxClusters ( 1000 )
48
- mmgc . setImageSize ( sampleImageData . width , sampleImageData . height )
49
- mmgc . setClassColor ( 0 , 0 )
50
- for ( let i = 0 ; i < colorInts . length ; i ++ ) {
51
- mmgc . setClassColor ( i + 1 , colorInts [ i ] )
52
- }
53
- const imageAddress = mmgc . getImageAddr ( )
54
- mmgc . HEAPU8 . set ( sampleImageData . data , imageAddress )
55
- mmgc . computeSuperPixels ( )
56
- superPixelsGenerated . current = "done"
57
- }
58
- if ( superPixelsGenerated . current !== "done" ) return
59
-
60
- // mmgc.setVerboseMode(true)
61
- if (
62
- ! [ "bg" , "background" , "nothing" ] . includes (
63
- regionClsList [ 0 ] . toLowerCase ( )
64
- )
65
- ) {
66
- console . log (
67
- `first region cls must be "bg" or "background" or "nothing"`
68
- )
69
- return
70
- }
71
- mmgc . clearClassElements ( )
72
- const classPoints = regions
73
- . filter ( ( r ) => r . type === "point" )
74
- . filter ( ( r ) => r . cls )
75
- for ( const classPoint of classPoints ) {
76
- if ( classPoint . x < 0 || classPoint . x >= 1 ) continue
77
- if ( classPoint . y < 0 || classPoint . y >= 1 ) continue
78
- const clsIndex = regionClsList . indexOf ( classPoint . cls )
79
- if ( clsIndex > colorInts . length ) {
80
- console . log ( "Too many classes to draw on mask!" )
81
- continue
82
- }
83
-
84
- mmgc . addClassPoint (
85
- clsIndex ,
86
- Math . floor ( classPoint . y * sampleImageData . height ) ,
87
- Math . floor ( classPoint . x * sampleImageData . width )
88
- )
89
- }
90
- const classPolygons = regions
91
- . map ( ( r ) => {
92
- if ( r . type !== "box" ) return r
93
- return {
94
- ...r ,
95
- type : "polygon" ,
96
- points : [
97
- [ r . x , r . y ] ,
98
- [ r . x + r . w , r . y ] ,
99
- [ r . x + r . w , r . y + r . h ] ,
100
- [ r . x , r . y + r . h ] ,
101
- ] ,
102
- }
103
- } )
104
- . filter ( ( r ) => r . type === "polygon" )
105
- . filter ( ( r ) => r . cls )
106
- for ( const polygon of classPolygons ) {
107
- const { points } = polygon
108
- const clsIndex = regionClsList . indexOf ( polygon . cls )
109
- const pi = mmgc . addPolygon ( clsIndex )
110
- const pointPairs = points . map ( ( p , i ) => [
111
- p ,
112
- points [ ( i + 1 ) % points . length ] ,
113
- ] )
114
- for ( const [ p1 , p2 ] of pointPairs ) {
115
- const ri1 = Math . round ( p1 [ 1 ] * sampleImageData . height )
116
- const ci1 = Math . round ( p1 [ 0 ] * sampleImageData . width )
117
- const ri2 = Math . round ( p2 [ 1 ] * sampleImageData . height )
118
- const ci2 = Math . round ( p2 [ 0 ] * sampleImageData . width )
119
- mmgc . addLineToPolygon ( pi , ri1 , ci1 , ri2 , ci2 )
120
- }
121
- }
122
79
123
- mmgc . computeMasks ( )
124
- const maskAddress = mmgc . getColoredMask ( )
125
- const cppImDataUint8 = new Uint8ClampedArray (
126
- mmgc . HEAPU8 . buffer ,
127
- maskAddress ,
128
- sampleImageData . data . length
129
- )
130
- const maskImageData = new ImageData (
131
- cppImDataUint8 ,
132
- sampleImageData . width ,
133
- sampleImageData . height
134
- )
80
+ const udtRegions = convertToUDTRegions ( regions )
135
81
136
- context . clearRect ( 0 , 0 , sampleImageData . width , sampleImageData . height )
137
- context . putImageData ( maskImageData , 0 , 0 )
82
+ autoseg . getMask ( udtRegions ) . then ( ( maskImageData ) => {
83
+ const context = canvasRef . getContext ( "2d" )
84
+ context . clearRect ( 0 , 0 , maskImageData . width , maskImageData . height )
85
+ context . putImageData ( maskImageData , 0 , 0 )
86
+ } )
138
87
} ,
139
88
1000 ,
140
89
[ canvasRef , sampleImageData , regions , hide ]
0 commit comments