PageRenderTime 34ms CodeModel.GetById 40ms RepoModel.GetById 1ms app.codeStats 0ms

/src/main.cc

https://github.com/rapmon/Face.js
C++ | 147 lines | 111 code | 34 blank | 2 comment | 6 complexity | 16888be5f9146774ffde8568f0e9e425 MD5 | raw file
  1. #include <v8.h>
  2. #include <node.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include "cv.h"
  6. #include "highgui.h"
  7. #include "main.h"
  8. #include "face_detection.h"
  9. using namespace node;
  10. using namespace v8;
  11. void Face::Init(Handle<Object> target)
  12. {
  13. HandleScope scope;
  14. s_ct = Persistent<FunctionTemplate>::New(FunctionTemplate::New(New));
  15. s_ct->InstanceTemplate()->SetInternalFieldCount(1);
  16. s_ct->SetClassName(String::NewSymbol("init"));
  17. Local<ObjectTemplate> proto = s_ct->PrototypeTemplate();
  18. proto->SetAccessor(String::NewSymbol("img"), GetImg, SetImg);
  19. proto->SetAccessor(String::NewSymbol("oncomplete"), GetOnComplete, SetOnComplete);
  20. proto->SetAccessor(String::NewSymbol("minsize"), GetMinSize, SetMinSize);
  21. proto->SetAccessor(String::NewSymbol("maxsize"), GetMaxSize, SetMaxSize);
  22. proto->SetAccessor(String::NewSymbol("pathto"), GetPathTo, SetPathTo);
  23. proto->SetAccessor(String::NewSymbol("checkSmile"), GetChkSmile, SetChkSmile);
  24. NODE_SET_PROTOTYPE_METHOD(s_ct, "run", Run);
  25. target->Set(String::NewSymbol("init"), s_ct->GetFunction());
  26. }
  27. Handle<Value> Face::New(const Arguments& args)
  28. {
  29. HandleScope scope;
  30. Face* fc = new Face();
  31. fc->Wrap(args.This());
  32. fc->memory = cvCreateMemStorage(0);
  33. fc->min_size = 20;
  34. fc->max_size = 0;
  35. fc->checkSmile = false;
  36. return args.This();
  37. }
  38. Handle<Value> Face::Run(const Arguments& args)
  39. {
  40. Face* fc = ObjectWrap::Unwrap<Face>(args.This());
  41. //TODO: Add checks of XML file, if it doesnt exist it dies
  42. char xmlCascade[255];
  43. sprintf(xmlCascade, "%shaarcascade_frontalface_alt2.xml", fc->pathto);
  44. fc->cascade = (CvHaarClassifierCascade*)cvLoad(xmlCascade, 0, 0, 0);
  45. fc->frame = cvLoadImage(fc->filename, 3);
  46. face_baton_t *baton = new face_baton_t();
  47. baton->fc = fc;
  48. fc->Ref();
  49. eio_custom(Analize, EIO_PRI_DEFAULT, AfterAnalize, baton);
  50. ev_ref(EV_DEFAULT_UC);
  51. return Undefined();
  52. }
  53. int Face::Analize(eio_req *req)
  54. {
  55. face_baton_t *baton = static_cast<face_baton_t *>(req->data);
  56. IplImage* gray_frame;
  57. gray_frame = nice_my_frame(baton->fc->frame);
  58. baton->fc->total_faces = detect_faces(gray_frame, baton->fc->cascade, baton->fc->memory, baton->fc->min_size, baton->fc->max_size);
  59. baton->fc->gray = gray_frame;
  60. //cvReleaseImage(&gray_frame);
  61. return 0;
  62. }
  63. int Face::AfterAnalize(eio_req *req)
  64. {
  65. HandleScope scope;
  66. face_baton_t *baton = static_cast<face_baton_t *>(req->data);
  67. ev_unref(EV_DEFAULT_UC);
  68. baton->fc->Unref();
  69. char xmlSmile[255];
  70. sprintf(xmlSmile, "%s/smiled_01.xml", baton->fc->pathto);
  71. CvHaarClassifierCascade* cascade_smile = (CvHaarClassifierCascade*)cvLoad(xmlSmile, 0, 0, 0);
  72. v8::Handle <v8::Array> arr = v8::Array::New();
  73. for(int i = 0; i < (baton->fc->total_faces ? baton->fc->total_faces->total : 0); i++ ) {
  74. CvRect* r = (CvRect*)cvGetSeqElem(baton->fc->total_faces, i );
  75. v8::Handle <v8::Object> obj = v8::Object::New();
  76. obj->Set(v8::String::New("x"), v8::Integer::New(r->x));
  77. obj->Set(v8::String::New("y"), v8::Integer::New(r->y));
  78. obj->Set(v8::String::New("width"), v8::Integer::New(r->width));
  79. obj->Set(v8::String::New("height"), v8::Integer::New(r->height));
  80. if(baton->fc->checkSmile == true) {
  81. cvSetImageROI(baton->fc->gray, cvRect(r->x+(r->width*1/7),r->y+(r->height*2/3),(int)r->width*6/7,(int)r->height/3));
  82. CvSeq* smile = cvHaarDetectObjects(baton->fc->gray, cascade_smile, baton->fc->memory, 1.1, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(22, 10), cvSize(0, 0));
  83. if(smile->total > 0) {
  84. CvAvgComp* comp = (CvAvgComp*)cvGetSeqElem(smile, 0);
  85. CvRect* r = (CvRect*)cvGetSeqElem(baton->fc->total_faces, i );
  86. obj->Set(v8::String::New("smile"), v8::Boolean::New(true));
  87. obj->Set(v8::String::New("intensity"), v8::Integer::New(comp->neighbors));
  88. } else {
  89. obj->Set(v8::String::New("smile"), v8::Boolean::New(false));
  90. }
  91. cvResetImageROI(baton->fc->gray);
  92. }
  93. arr->Set(i, obj);
  94. }
  95. cvClearMemStorage(baton->fc->memory);
  96. v8::Handle<v8::Value> args[1] = {arr};
  97. TryCatch try_catch;
  98. baton->fc->oncomplete->Call(Context::GetCurrent()->Global(), 1, args);
  99. if (try_catch.HasCaught()) {
  100. FatalException(try_catch);
  101. }
  102. baton->cb.Dispose();
  103. delete baton;
  104. return 0;
  105. }
  106. Persistent<FunctionTemplate> Face::s_ct;
  107. extern "C" {
  108. static void init (Handle<Object> target)
  109. {
  110. Face::Init(target);
  111. }
  112. NODE_MODULE(face, init);
  113. }