Raspberry Pi - Gesichtserkennung

Gast #3071111
Lesenswert?

OpenCV ist auf dem Pi VERDAMMT langsam, ohne bearbeitung schätz ich das 
ganze auf ca. 2-3 fps..
Ich denke wenn das Kameramodul endlich verfügbar ist, kann man etwas mit 
GPU unterstützung machen, aber das ist noch Zukunftsmusik.
Auch möglich wäre die (unsichere) Gesichtserkennung von Android zu 
portieren, das scheint ja auch auf verhältnismäßig langsamen Geräten zu 
Funktionieren.
Gast #3934431
Lesenswert?

Programmierung Gesichtserkennung mit der Web-Camera

Author D.Selzer-McKenzie
1
import processing.video.*;
2

3
import monclubelec.javacvPro.*;
4

5
import java.awt.*; // pour classes Point , Rectangle..
6

7
import java.util.*;
8

9
// Für WebCam:
10

11
Capture cam1;
12

13
//GSMovie cam1;
14

15
 
16

17
OpenCV opencv; // deklariert ein OpenCV Objekt
18

19
Rectangle[] faceRect;
20

21
 
22

23
// A list of my Face objects
24

25
ArrayList<Face> faceList;
26

27
 
28

29
// how many have I found over all time
30

31
int faceCount = 0;
32

33
 
34

35
float  sum=0;
36

37
int scl=1;
38

39
int frame=0;
40

41
boolean delFaces;
42

43
 
44

45
void setup() {
46

47
 
48

49
// Für WebCam:
50

51
cam1= new Capture(this, 1280, 720);
52

53
//cam1 = new GSMovie(this, "maus.mov");
54

55
 
56

57
// für WebCam auskommentieren:
58

59
//cam1.play();
60

61
cam1.start();
62

63
 
64

65
// initialisiert OpenCV ---
66

67
opencv = new OpenCV(this);
68

69
 
70

71
//Vorsicht: bei der Arbeit mit einer Datei muss die Größe genau passen!!!
72

73
//opencv.allocate(640, 360);
74

75
opencv.allocate(cam1.width, cam1.height);
76

77
 
78

79
// Für WebCam:
80

81
// opencv.allocate(cam1.getSourceWidth(), cam1.getSourceHeight()); // initialisiert die Buffer von OpenCV
82

83
size (opencv.width(), opencv.height());
84

85
 
86

87
// Laden Beschreibungsdatei
88

89
opencv.cascade("/usr/share/opencv/haarcascades/", "haarcascade_frontalface_alt_tree.xml");
90

91
 
92

93
// Liste mit den Gesichtsobjekten
94

95
faceList = new ArrayList<Face>();
96

97
}
98

99
 
100

101
void draw() {
102

103
 
104

105
// Dateien und die WebCam brauchen etwas Zeit zum Laden
106

107
if (cam1.available()) {
108

109
 
110

111
// Einzelne Frames werden gelesen
112

113
cam1.read();
114

115
opencv.copy(cam1);
116

117
 
118

119
// Schnitt oder Kameraschwenk erkennen
120

121
println(abs(opencv.sum()-sum)/1000000);
122

123
if (abs(opencv.sum()-sum)/1000000 >7) delFaces=true;
124

125
else delFaces=false;
126

127
sum=opencv.sum();
128

129
 
130

131
// Erkennen
132

133
faceRect = opencv.detect(false);
134

135
 
136

137
image(opencv.getBuffer(), 0, 0);
138

139
 
140

141
//Rechteck zeichnen
142

143
//opencv.drawRectDetect(true);
144

145
 
146

147
// Code ab hier von Daniel Shiffman
148

149
// SCENARIO 1: faceList is empty
150

151
if (faceList.isEmpty()) {
152

153
// Just make a Face object for every face Rectangle
154

155
for (int i = 0; i < faceRect.length; i++) {
156

157
faceList.add(new Face(faceRect[i].x, faceRect[i].y, faceRect[i].width, faceRect[i].height));
158

159
}
160

161
// SCENARIO 2: We have fewer Face objects than face Rectangles found from OPENCV
162

163
}
164

165
else if (faceList.size() <= faceRect.length) {
166

167
boolean[] used = new boolean[faceRect.length];
168

169
// Match existing Face objects with a Rectangle
170

171
for (Face f : faceList) {
172

173
// Find faces[index] that is closest to face f
174

175
// set used[index] to true so that it can't be used twice
176

177
float record = 50000;
178

179
int index = -1;
180

181
for (int i = 0; i < faceRect.length; i++) {
182

183
float d = dist(faceRect[i].x, faceRect[i].y, f.r.x, f.r.y);
184

185
if (d < record && !used[i]) {
186

187
record = d;
188

189
index = i;
190

191
}
192

193
}
194

195
// Update Face object location
196

197
used[index] = true;
198

199
f.update(faceRect[index]);
200

201
}
202

203
// Add any unused faces
204

205
for (int i = 0; i < faceRect.length; i++) {
206

207
if (!used[i]) {
208

209
faceList.add(new Face(faceRect[i].x, faceRect[i].y, faceRect[i].width, faceRect[i].height));
210

211
}
212

213
}
214

215
// SCENARIO 3: We have more Face objects than face Rectangles found
216

217
}
218

219
else {
220

221
// All Face objects start out as available
222

223
for (Face f : faceList) {
224

225
f.available = true;
226

227
}
228

229
// Match Rectangle with a Face object
230

231
for (int i = 0; i < faceRect.length; i++) {
232

233
// Find face object closest to faces[i] Rectangle
234

235
// set available to false
236

237
float record = 50000;
238

239
int index = -1;
240

241
for (int j = 0; j < faceList.size(); j++) {
242

243
Face f = faceList.get(j);
244

245
float d = dist(faceRect[i].x, faceRect[i].y, f.r.x, f.r.y);
246

247
if (d < record && f.available) {
248

249
record = d;
250

251
index = j;
252

253
}
254

255
}
256

257
// Update Face object location
258

259
Face f = faceList.get(index);
260

261
f.available = false;
262

263
f.update(faceRect[i]);
264

265
}
266

267
// Start to kill any left over Face objects
268

269
for (Face f : faceList) {
270

271
if (f.available) {
272

273
f.countDown();
274

275
if (f.dead()) {
276

277
f.delete = true;
278

279
}
280

281
}
282

283
}
284

285
}
286

287
 
288

289
// Delete any that should be deleted
290

291
for (int i = faceList.size()-1; i >= 0; i--) {
292

293
Face f = faceList.get(i);
294

295
// Bei einem Schnitt werden alle Gesichter sofort gelöscht
296

297
if (f.delete || delFaces) {
298

299
faceList.remove(i);
300

301
}
302

303
}
304

305
 
306

307
// Draw all the faces
308

309
for (int i = 0; i < faceRect.length; i++) {
310

311
noFill();
312

313
stroke(255, 0, 0);
314

315
rect(faceRect[i].x*scl, faceRect[i].y*scl, faceRect[i].width*scl, faceRect[i].height*scl);
316

317
}
318

319
 
320

321
for (Face f : faceList) {
322

323
f.display();
324

325
}
326

327
}
328

329
}
330

331
 
332

333
void keyReleased() {
334

335
if (key == 's' || key == 'S') saveFrame(timestamp()+"_##.png");
336

337
 
338

339
// for Movie
340

341
//frame+=500;
342

343
//cam1.jump(frame);
344

345
//cam1.play();
346

347
}
348

349
 
350

351
// timestamp
352

353
String timestamp() {
354

355
Calendar now = Calendar.getInstance();
356

357
return String.format("%1$ty%1$tm%1$td_%1$tH%1$tM%1$tS", now);
358

359
}
360

361
 
362

363
// Which Face Is Which
364

365
// Daniel Shiffman
366

367
// April 25, 2011
368

369
// http://www.shiffman.net
370

371
 
372

373
class Face {
374

375
 
376

377
// A Rectangle
378

379
Rectangle r;
380

381
 
382

383
// Am I available to be matched?
384

385
boolean available;
386

387
 
388

389
// Should I be deleted?
390

391
boolean delete;
392

393
 
394

395
// How long should I live if I have disappeared?
396

397
int timer = 63;
398

399
 
400

401
// Assign a number to each face
402

403
int id;
404

405
 
406

407
// Make me
408

409
Face(int x, int y, int w, int h) {
410

411
r = new Rectangle(x, y, w, h);
412

413
available = true;
414

415
delete = false;
416

417
id = faceCount;
418

419
faceCount++;
420

421
}
422

423
 
424

425
// Show me
426

427
void display() {
428

429
fill(0, 0, 255, timer*2);
430

431
stroke(0, 0, 255);
432

433
rect(r.x*scl, r.y*scl, r.width*scl, r.height*scl);
434

435
fill(255, timer*2);
436

437
text(""+id, r.x*scl+10, r.y*scl+30);
438

439
}
440

441
 
442

443
// Give me a new location / size
444

445
// Oooh, it would be nice to lerp here!
446

447
void update(Rectangle newR) {
448

449
r = (Rectangle) newR.clone();
450

451
}
452

453
 
454

455
// Count me down, I am gone
456

457
void countDown() {
458

459
timer--;
460

461
}
462

463
 
464

465
// I am deed, delete me
466

467
boolean dead() {
468

469
if (timer < 0) return true;
470

471
return false;
472

473
}
474

475
}

--
Quelltext in [ c ] [ /c ] einschließen.

Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

-rufus
(Firma: RUB) #3934705
Lesenswert?

xvzf schrieb:
> OpenCV ist auf dem Pi VERDAMMT langsam
Die Himbeer-Alternative besorgen: Odroid C1
Raspberry mit quadcore, 1,5GHz, 1GB RAM usw, aber zum aehnlichen Preis 
wie die Himmbeere.
http://www.heise.de/hardware-hacks/meldung/Odroid-C1-Raspberry-Pi-Konkurrent-in-den-Startloechern-2487225.html
http://www.hardkernel.com/main/products/prdt_info.php?g_code=G141578608433

Hier bestellen:
http://www.pollin.de/shop/dt/MTI2OTgxOTk-/Bausaetze_Module/Entwicklerboards/ODROID_C1_Einplatinen_Computer_1_5_GHz_QuadCore_4x_USB_1_GB.html

PiPi schrieb:
> Ich möchte dieses Feature gerne für ein Projekt nutzen. Kennt jemand
> gute Opensource Lösungen, die auf einem Raspberry Pi laufen?
Wie gesagt: OpenCV (C++) oder PyCV (das selbe nur fuer Python)
Auf dem RPi wuerd ich aber C++ vorziehen.

Fuer 'Face Tracking' bzw. Gesichtserkennung mit OpenCV gibt es auch 
viele Beispiele im Netz, das kannst du dann ja so anpassen, wie du es 
brauchst.
http://mymobilerobots.com/myblog/academic/tutorial-opencv-2-4-3-face-tracking-detection-using-vs-2010-c/
http://opencv-code.com/tutorials/eye-detection-and-tracking/
http://www.instructables.com/id/Face-detection-and-tracking-with-Arduino-and-OpenC/

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren