5
5
using OpenCVForUnity . ImgprocModule ;
6
6
using OpenCVForUnity . ObjdetectModule ;
7
7
using System ;
8
+ using System . Linq ;
9
+ using System . Runtime . InteropServices ;
8
10
using System . Text ;
9
11
using UnityEngine ;
10
12
@@ -121,26 +123,22 @@ public virtual void visualize(Mat image, Mat results, bool print_results = false
121
123
if ( results . empty ( ) || results . cols ( ) < 15 )
122
124
return ;
123
125
124
- for ( int i = results . rows ( ) - 1 ; i >= 0 ; -- i )
126
+ DetectionData [ ] data = getData ( results ) ;
127
+
128
+ foreach ( var d in data . Reverse ( ) )
125
129
{
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 ;
137
135
138
136
Scalar bbc = bBoxColor ;
139
137
Scalar bbcolor = isRGB ? bbc : new Scalar ( bbc . val [ 2 ] , bbc . val [ 1 ] , bbc . val [ 0 ] , bbc . val [ 3 ] ) ;
140
138
141
139
Imgproc . rectangle ( image , new Point ( left , top ) , new Point ( right , bottom ) , bbcolor , 2 ) ;
142
140
143
- string label = String . Format ( "{0:0.0000}" , conf [ 0 ] ) ;
141
+ string label = String . Format ( "{0:0.0000}" , score ) ;
144
142
int [ ] baseLine = new int [ 1 ] ;
145
143
Size labelSize = Imgproc . getTextSize ( label , Imgproc . FONT_HERSHEY_SIMPLEX , 0.5 , 1 , baseLine ) ;
146
144
@@ -150,37 +148,42 @@ public virtual void visualize(Mat image, Mat results, bool print_results = false
150
148
Imgproc . putText ( image , label , new Point ( left , top ) , Imgproc . FONT_HERSHEY_SIMPLEX , 0.5 , new Scalar ( 0 , 0 , 0 , 255 ) , 1 , Imgproc . LINE_AA ) ;
151
149
152
150
// 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 ) ;
160
161
}
161
162
162
163
// Print results
163
164
if ( print_results )
164
165
{
165
166
StringBuilder sb = new StringBuilder ( ) ;
166
167
167
- for ( int i = 0 ; i < results . rows ( ) ; ++ i )
168
+ for ( int i = 0 ; i < data . Length ; ++ i )
168
169
{
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 ;
175
176
176
177
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 ) ) ;
179
180
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
+
184
187
sb . AppendLine ( ) ;
185
188
}
186
189
@@ -198,6 +201,55 @@ public virtual void dispose()
198
201
199
202
input_sizeMat = null ;
200
203
}
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
+ }
201
253
}
202
254
}
203
255
#endif
0 commit comments