/**
 *  数据转换
 */ import { EToolName } from '@/constant/store' ; import { IFileInfo } from '@/store' ; import { jsonParser } from './tool/common' ; import { DrawUtils } from '@labelbee/lb-annotation' ; import ColorCheatSheet from '@/assets/color.json' ; export const getRgbFromColorCheatSheet = ( index ) => { const rgb = ColorCheatSheet [ index ] . rgb ; return `rgb(${ rgb . r },${ rgb . g },${ rgb . b })` ; } ; export const getRgbaColorListFromColorCheatSheet = ( index ) => { const rgb = ColorCheatSheet [ index ] . rgb ; return [ rgb . r , rgb . g , rgb . b , 255 ] ; } ; interface CocoDataFormat { images : Array < ICocoImage > ; annotations : Array < ICocoObjectDetection > ; category : Array < { id : number ; name : string ; supercategory : string ; } > ; } interface ICocoImage { id : number ; width : number ; height : number ; file_name : string ; valid ? : boolean ; rotate ? : number ; } interface ICocoObjectDetection { id : number ; image_id : number ; category_id : number ; segmentation : number [ ] ; area : number ; bbox : number [ ] ; iscrowd : 0 | 1 ; textAttribute ? : string ; order ? : number ; valid ? : boolean ; } /**
 * 平台默认多边形
 */ interface IDefaultPolygon { x : number ; y : number ; } export default class DataTransfer { param pointList returns public static transferPolygon2CocoPolygon ( pointList ) { return pointList . reduce < number [ ] > ( ( acc , cur ) => [ ... acc , cur . x , cur . y ] , [ ] ) ; } param pointList returns public static getPolygonArea ( pointList ) { let total = 0 ; for ( let i = 0 , l = pointList . length ; i < l ; i ++ ) { const addX = pointList [ i ] . x ; const addY = pointList [ i == pointList . length - 1 ? 0 : i + 1 ] . y ; const subX = pointList [ i == pointList . length - 1 ? 0 : i + 1 ] . x ; const subY = pointList [ i ] . y ; total += addX * addY * 0.5 ; total -= subX * subY * 0.5 ; } return Math . abs ( total ) ; } param pointList returns public static getPolygonBbox ( pointList ) { if ( pointList . length < 3 || ! pointList . length ) { return 0 ; } let ltx = Number . MAX_SAFE_INTEGER ; let lty = Number . MAX_SAFE_INTEGER ; let rbx = 0 ; let rby = 0 ; pointList . forEach ( ( polygon ) => { if ( polygon . x < ltx ) { ltx = polygon . x ; } if ( polygon . y < lty ) { lty = polygon . y ; } if ( polygon . x > rbx ) { rbx = polygon . x ; } if ( polygon . y > rby ) { rby = polygon . y ; } } ) ; return [ ltx , lty , rbx - ltx , rby - lty ] ; } param fileList public static transferDefault2Coco ( fileList ) { const mainObject = { images : [ ] , annotations : [ ] , category : [ { id : 0 , name : '' , supercategory : '' , } , ] , } ; let image_id = 1 ; let result_id = 1 ; fileList . forEach ( ( info ) => { const result = jsonParser ( info . result ) ; const images = { id : image_id , file_name : info . url , width : result ?. width ?? 0 , height : result ?. height ?? 0 , valid : result ?. valid ?? true , rotate : result ?. rotate ?? 0 , } ; const annotation = [ ] ; const getCategoryID = ( data ) => { let category_id = 0 ; if ( data ?. attribute ) { const category = mainObject . category . find ( ( v ) => v . name === data . attribute ) ; if ( category ) { category_id = category . id ; } else { category_id = mainObject . category . length + 1 ; mainObject . category . push ( { id : category_id , name : data . attribute , supercategory : '' , } ) ; } } return category_id ; } ; const step1Result = result [ 'step_1' ] ?. result ; switch ( result [ 'step_1' ] ?. toolName ) { case EToolName . Rect : step1Result ?. forEach ( ( rect ) => { let category_id = getCategoryID ( rect ) ; const defaultData = { image_id , id : result_id , bbox : [ rect . x , rect . y , rect . width , rect . height ] , iscrowd : 0 , segmentation : [ ] , category_id , } ; let area = 0 ; if ( rect . width && rect . height ) { area = rect . width * rect . height ; } Object . assign ( defaultData , { area } ) ; if ( rect . textAttribute ) { Object . assign ( defaultData , { textAttribute : rect . textAttribute } ) ; } if ( rect . order ) { Object . assign ( defaultData , { order : rect . order } ) ; } annotation . push ( defaultData ) ; result_id ++ ; } ) ; break ; case EToolName . Polygon : step1Result ?. forEach ( ( polygon ) => { let category_id = getCategoryID ( polygon ) ; const defaultData = { image_id , id : result_id , iscrowd : 0 , segmentation : [ this . transferPolygon2CocoPolygon ( polygon . pointList ) ] , area : this . getPolygonArea ( polygon . pointList ) , bbox : this . getPolygonBbox ( polygon . pointList ) , category_id , } ; if ( polygon . textAttribute ) { Object . assign ( defaultData , { textAttribute : polygon . textAttribute } ) ; } if ( polygon . order ) { Object . assign ( defaultData , { order : polygon . order } ) ; } annotation . push ( defaultData ) ; result_id ++ ; } ) ; break ; default : { } } mainObject . images . push ( images ) ; mainObject . annotations = mainObject . annotations . concat ( annotation ) ; image_id ++ ; } ) ; return mainObject ; } param width param height param polygon param defaultKeyList returns public static transferPolygon2ADE20k ( width , height , polygon , defaultKeyList = [ ] ) { const canvas = document . createElement ( 'canvas' ) ; canvas . width = width ; canvas . height = height ; const keyList = [ ... defaultKeyList ] ; DrawUtils . drawRectWithFill ( canvas , { x : 0 , y : 0 , width , height } , { color : `rgb(0, 0, 0)` } ) ; if ( polygon . length > 0 ) { polygon . forEach ( ( p ) => { let key = '' ; if ( p . attribute ) { key = p . attribute ; } let colorIndex = keyList . findIndex ( ( v ) => v === key ) ; if ( colorIndex === - 1 ) { keyList . push ( key ) ; colorIndex = keyList . length - 1 ; } DrawUtils . drawPolygonWithFill ( canvas , p . pointList , { color : getRgbFromColorCheatSheet ( colorIndex + 1 ) , } ) ; } ) ; } const MIME_TYPE = 'image/png' ; const url = canvas . toDataURL ( MIME_TYPE , 1 ) ; const base64Data = url . replace ( /^data:image\/png;base64,/ , '' ) ; return [ base64Data , keyList ] ; } param width param height param polygon param defaultKeyList returns public static transferPolygon2Gray ( width , height , polygon , defaultKeyList = [ ] ) { const canvas = document . createElement ( 'canvas' ) ; canvas . width = width ; canvas . height = height ; const keyList = [ ... defaultKeyList ] ; DrawUtils . drawRectWithFill ( canvas , { x : 0 , y : 0 , width , height } , { color : `rgb(0, 0, 0)` } ) ; if ( polygon . length > 0 ) { polygon . forEach ( ( p ) => { let key = '' ; if ( p . attribute ) { key = p . attribute ; } let colorIndex = keyList . findIndex ( ( v ) => v === key ) ; if ( colorIndex === - 1 ) { keyList . push ( key ) ; colorIndex = keyList . length - 1 ; } const trainIds = colorIndex + 1 ; DrawUtils . drawPolygonWithFill ( canvas , p . pointList , { color : `rgb(${ trainIds },${ trainIds },${ trainIds })` , } ) ; } ) ; } const MIME_TYPE = 'image/png' ; const url = canvas . toDataURL ( MIME_TYPE , 1 ) ; const base64Data = url . replace ( /^data:image\/png;base64,/ , '' ) ; return [ base64Data , keyList ] ; } }