@@ -4,8 +4,44 @@ import React, { useState, useEffect, useMemo, useRef } from "react"
44import { colorInts } from "../colors"
55import { useDebounce } from "react-use"
66import loadImage from "./load-image"
7+ import autoseg from "autoseg/webworker"
78
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+ }
945
1046export const ImageMask = ( {
1147 regions,
@@ -16,18 +52,20 @@ export const ImageMask = ({
1652 hide = false ,
1753 autoSegmentationOptions = { type : "simple" } ,
1854} ) => {
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
2157 const [ canvasRef , setCanvasRef ] = useState ( null )
2258
23- const superPixelsGenerated = useRef ( false )
2459 const [ sampleImageData , setSampleImageData ] = useState ( )
2560
2661 useEffect ( ( ) => {
2762 if ( ! imageSrc ) return
2863
2964 loadImage ( imageSrc ) . then ( ( imageData ) => {
30- superPixelsGenerated . current = false
65+ autoseg . setConfig ( {
66+ classNames : regionClsList ,
67+ } )
68+ autoseg . loadImage ( imageData )
3169 setSampleImageData ( imageData )
3270 } )
3371 } , [ imageSrc ] )
@@ -38,103 +76,14 @@ export const ImageMask = ({
3876 if ( ! canvasRef ) return
3977 if ( ! sampleImageData ) return
4078 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- }
12279
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 )
13581
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+ } )
13887 } ,
13988 1000 ,
14089 [ canvasRef , sampleImageData , regions , hide ]
0 commit comments