55using OpenCVForUnity . ImgprocModule ;
66using OpenCVForUnity . ObjdetectModule ;
77using System ;
8+ using System . Linq ;
9+ using System . Runtime . InteropServices ;
810using System . Text ;
911using UnityEngine ;
1012
@@ -121,26 +123,22 @@ public virtual void visualize(Mat image, Mat results, bool print_results = false
121123 if ( results . empty ( ) || results . cols ( ) < 15 )
122124 return ;
123125
124- for ( int i = results . rows ( ) - 1 ; i >= 0 ; -- i )
126+ DetectionData [ ] data = getData ( results ) ;
127+
128+ foreach ( var d in data . Reverse ( ) )
125129 {
126- float [ ] box = new float [ 4 ] ;
127- results . get ( i , 0 , box ) ;
128- float [ ] conf = new float [ 1 ] ;
129- results . get ( i , 14 , conf ) ;
130- float [ ] landmarks = new float [ 10 ] ;
131- results . get ( i , 4 , landmarks ) ;
132-
133- float left = box [ 0 ] ;
134- float top = box [ 1 ] ;
135- float right = box [ 0 ] + box [ 2 ] ;
136- float bottom = box [ 1 ] + box [ 3 ] ;
130+ float left = d . xy . x ;
131+ float top = d . xy . y ;
132+ float right = d . xy . x + d . wh . x ;
133+ float bottom = d . xy . y + d . wh . y ;
134+ float score = d . score ;
137135
138136 Scalar bbc = bBoxColor ;
139137 Scalar bbcolor = isRGB ? bbc : new Scalar ( bbc . val [ 2 ] , bbc . val [ 1 ] , bbc . val [ 0 ] , bbc . val [ 3 ] ) ;
140138
141139 Imgproc . rectangle ( image , new Point ( left , top ) , new Point ( right , bottom ) , bbcolor , 2 ) ;
142140
143- string label = String . Format ( "{0:0.0000}" , conf [ 0 ] ) ;
141+ string label = String . Format ( "{0:0.0000}" , score ) ;
144142 int [ ] baseLine = new int [ 1 ] ;
145143 Size labelSize = Imgproc . getTextSize ( label , Imgproc . FONT_HERSHEY_SIMPLEX , 0.5 , 1 , baseLine ) ;
146144
@@ -150,37 +148,42 @@ public virtual void visualize(Mat image, Mat results, bool print_results = false
150148 Imgproc . putText ( image , label , new Point ( left , top ) , Imgproc . FONT_HERSHEY_SIMPLEX , 0.5 , new Scalar ( 0 , 0 , 0 , 255 ) , 1 , Imgproc . LINE_AA ) ;
151149
152150 // draw landmark points
153- for ( int j = 0 ; j < 10 ; j += 2 )
154- {
155- Scalar c = keyPointsColors [ ( j / 2 ) % keyPointsColors . Length ] ;
156- Scalar color = isRGB ? c : new Scalar ( c . val [ 2 ] , c . val [ 1 ] , c . val [ 0 ] , c . val [ 3 ] ) ;
157-
158- Imgproc . circle ( image , new Point ( landmarks [ j ] , landmarks [ j + 1 ] ) , 2 , color , 2 ) ;
159- }
151+ Imgproc . circle ( image , new Point ( d . rightEye . x , d . rightEye . y ) , 2 ,
152+ isRGB ? keyPointsColors [ 0 ] : new Scalar ( keyPointsColors [ 0 ] . val [ 2 ] , keyPointsColors [ 0 ] . val [ 1 ] , keyPointsColors [ 0 ] . val [ 0 ] , keyPointsColors [ 0 ] . val [ 3 ] ) , 2 ) ;
153+ Imgproc . circle ( image , new Point ( d . leftEye . x , d . leftEye . y ) , 2 ,
154+ isRGB ? keyPointsColors [ 1 ] : new Scalar ( keyPointsColors [ 1 ] . val [ 2 ] , keyPointsColors [ 1 ] . val [ 1 ] , keyPointsColors [ 1 ] . val [ 0 ] , keyPointsColors [ 1 ] . val [ 3 ] ) , 2 ) ;
155+ Imgproc . circle ( image , new Point ( d . nose . x , d . nose . y ) , 2 ,
156+ isRGB ? keyPointsColors [ 2 ] : new Scalar ( keyPointsColors [ 2 ] . val [ 2 ] , keyPointsColors [ 2 ] . val [ 1 ] , keyPointsColors [ 2 ] . val [ 0 ] , keyPointsColors [ 2 ] . val [ 3 ] ) , 2 ) ;
157+ Imgproc . circle ( image , new Point ( d . rightMouth . x , d . rightMouth . y ) , 2 ,
158+ isRGB ? keyPointsColors [ 3 ] : new Scalar ( keyPointsColors [ 3 ] . val [ 2 ] , keyPointsColors [ 3 ] . val [ 1 ] , keyPointsColors [ 3 ] . val [ 0 ] , keyPointsColors [ 3 ] . val [ 3 ] ) , 2 ) ;
159+ Imgproc . circle ( image , new Point ( d . leftMouth . x , d . leftMouth . y ) , 2 ,
160+ isRGB ? keyPointsColors [ 4 ] : new Scalar ( keyPointsColors [ 4 ] . val [ 2 ] , keyPointsColors [ 4 ] . val [ 1 ] , keyPointsColors [ 4 ] . val [ 0 ] , keyPointsColors [ 4 ] . val [ 3 ] ) , 2 ) ;
160161 }
161162
162163 // Print results
163164 if ( print_results )
164165 {
165166 StringBuilder sb = new StringBuilder ( ) ;
166167
167- for ( int i = 0 ; i < results . rows ( ) ; ++ i )
168+ for ( int i = 0 ; i < data . Length ; ++ i )
168169 {
169- float [ ] box = new float [ 4 ] ;
170- results . get ( i , 0 , box ) ;
171- float [ ] conf = new float [ 1 ] ;
172- results . get ( i , 14 , conf ) ;
173- float [ ] landmarks = new float [ 10 ] ;
174- results . get ( i , 4 , landmarks ) ;
170+ var d = data [ i ] ;
171+ float left = d . xy . x ;
172+ float top = d . xy . y ;
173+ float right = d . xy . x + d . wh . x ;
174+ float bottom = d . xy . y + d . wh . y ;
175+ float score = d . score ;
175176
176177 sb . AppendLine ( String . Format ( "-----------face {0}-----------" , i + 1 ) ) ;
177- sb . AppendLine ( String . Format ( "conf : {0:0.0000}" , conf [ 0 ] ) ) ;
178- sb . AppendLine ( String . Format ( "box: {0:0} {1:0} {2:0} {3:0}" , box [ 0 ] , box [ 1 ] , box [ 2 ] , box [ 3 ] ) ) ;
178+ sb . AppendLine ( String . Format ( "score : {0:0.0000}" , score ) ) ;
179+ sb . AppendLine ( String . Format ( "box: {0:0} {1:0} {2:0} {3:0}" , left , top , right , bottom ) ) ;
179180 sb . Append ( "landmarks: " ) ;
180- foreach ( var p in landmarks )
181- {
182- sb . Append ( String . Format ( "{0:0} " , p ) ) ;
183- }
181+ sb . Append ( String . Format ( "{0:0} {1:0} " , d . rightEye . x , d . rightEye . y ) ) ;
182+ sb . Append ( String . Format ( "{0:0} {1:0} " , d . leftEye . x , d . leftEye . y ) ) ;
183+ sb . Append ( String . Format ( "{0:0} {1:0} " , d . nose . x , d . nose . y ) ) ;
184+ sb . Append ( String . Format ( "{0:0} {1:0} " , d . rightMouth . x , d . rightMouth . y ) ) ;
185+ sb . Append ( String . Format ( "{0:0} {1:0} " , d . leftMouth . x , d . leftMouth . y ) ) ;
186+
184187 sb . AppendLine ( ) ;
185188 }
186189
@@ -198,6 +201,55 @@ public virtual void dispose()
198201
199202 input_sizeMat = null ;
200203 }
204+
205+ [ StructLayout ( LayoutKind . Sequential ) ]
206+ public readonly struct DetectionData
207+ {
208+ // Bounding box
209+ public readonly Vector2 xy ;
210+ public readonly Vector2 wh ;
211+
212+ // Key points
213+ public readonly Vector2 rightEye ;
214+ public readonly Vector2 leftEye ;
215+ public readonly Vector2 nose ;
216+ public readonly Vector2 rightMouth ;
217+ public readonly Vector2 leftMouth ;
218+
219+ // Confidence score [0, 1]
220+ public readonly float score ;
221+
222+ // sizeof(DetectionData)
223+ public const int Size = 15 * sizeof ( float ) ;
224+
225+ public DetectionData ( Vector2 xy , Vector2 wh , Vector2 rightEye , Vector2 leftEye , Vector2 nose , Vector2 rightMouth , Vector2 leftMouth , float score )
226+ {
227+ this . xy = xy ;
228+ this . wh = wh ;
229+ this . rightEye = rightEye ;
230+ this . leftEye = leftEye ;
231+ this . nose = nose ;
232+ this . rightMouth = rightMouth ;
233+ this . leftMouth = leftMouth ;
234+ this . score = score ;
235+ }
236+
237+ public override string ToString ( )
238+ {
239+ return "xy:" + xy + " wh:" + wh + " rightEye:" + rightEye + " leftEye:" + leftEye + " nose:" + nose + " rightMouth:" + rightMouth + " leftMouth:" + leftMouth + " score:" + score ;
240+ }
241+ } ;
242+
243+ public virtual DetectionData [ ] getData ( Mat results )
244+ {
245+ if ( results . empty ( ) )
246+ return new DetectionData [ 0 ] ;
247+
248+ var dst = new DetectionData [ results . rows ( ) ] ;
249+ OpenCVForUnity . UtilsModule . MatUtils . copyFromMat ( results , dst ) ;
250+
251+ return dst ;
252+ }
201253 }
202254}
203255#endif
0 commit comments