static void ProcessShapes( const ShapeFile& sh, // in FILE* fitfile) // in { Pacifier pacifier(sh.nshapes_); // only used if quiet_g for (int ishape = 0; ishape < sh.nshapes_; ishape++) { if (quiet_g) pacifier.Print_(ishape); else { if (sh.nshapes_ > 1) lprintf("%*d ", NumDigits(sh.nshapes_), ishape); lprintf("%*.*s:%s", sh.nchar_, sh.nchar_, sh.bases_[ishape].c_str(), trace_g? "\n": " "); } if (ignore_multiface_imgs_g && (sh.bits_[ishape] & AT_MultiFace)) { printf_g("multiple face, skipping\n"); continue; // note continue } const char* imgpath = PathGivenDirs(sh.bases_[ishape], sh.dirs_, sh.shapepath_); Image img(cv::imread(imgpath, CV_LOAD_IMAGE_GRAYSCALE)); if (!img.data) Err("Cannot load %s", imgpath); const clock_t start_time = clock(); const Shape refshape(sh.shapes_[ishape]); const Shape refshape17(Shape17OrEmpty(refshape)); if (refshape17.rows) // converted to a Shape17? SanityCheckShape17(refshape17); if (!stasm_open_image((const char*)img.data, img.cols, img.rows, imgpath, 0 /*multi*/, minwidth_g)) Err("stasm_open_image failed: %s", stasm_lasterr()); clock_t start_time1 = clock(); const double facedet_time = double(start_time1 - start_time) / CLOCKS_PER_SEC; int foundface = false; float estyaw = 0; // estimated yaw float landmarks[2 * stasm_NLANDMARKS]; // x,y coords if (!stasm_search_auto_ext(&foundface, landmarks, &estyaw)) Err("stasm_search_auto failed: %s", stasm_lasterr()); const Shape shape(LandmarksAsShape(landmarks)); const double asmsearch_time = double(clock() - start_time) / CLOCKS_PER_SEC; ProcessFace(img, imgpath, foundface, shape, estyaw, facedet_time, asmsearch_time, refshape, fitfile, sh, ishape); } if (quiet_g) { pacifier.End_(); printf("\n"); } }
static PyObject* Py_init( PyObject* self, PyObject* args, PyObject* kwargs) { const char* datadir = PyStr_AS_STRING(datadir_default); int trace = 0; static const char* kwlist[] = {"datadir", "trace", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|si:init", const_cast<char**>(kwlist), &datadir, &trace)) return NULL; if (trace != 0 && trace != 1) { PyErr_SetString(PyExc_TypeError, trace_error); return NULL; } if (!stasm_init(datadir, trace)) { PyErr_SetString(StasmException, stasm_lasterr()); return NULL; } Py_RETURN_NONE; }
int main() { if (!stasm_init("../data", 0 /*trace*/)) error("stasm_init failed: ", stasm_lasterr()); static const char* path = "../data/testface.jpg"; cv::Mat_<unsigned char> img(cv::imread(path, CV_LOAD_IMAGE_GRAYSCALE)); if (!img.data) error("Cannot load", path); if (!stasm_open_image((const char*)img.data, img.cols, img.rows, path, 1 /*multiface*/, 10 /*minwidth*/)) error("stasm_open_image failed: ", stasm_lasterr()); int foundface; float landmarks[2 * stasm_NLANDMARKS]; // x,y coords (note the 2) int nfaces = 0; while (1) { if (!stasm_search_auto(&foundface, landmarks)) error("stasm_search_auto failed: ", stasm_lasterr()); if (!foundface) break; // note break // for demonstration, convert from Stasm 77 points to XM2VTS 68 points stasm_convert_shape(landmarks, 68); // draw the landmarks on the image as white dots stasm_force_points_into_image(landmarks, img.cols, img.rows); for (int i = 0; i < stasm_NLANDMARKS; i++) img(cvRound(landmarks[i*2+1]), cvRound(landmarks[i*2])) = 255; nfaces++; } printf("%s: %d face(s)\n", path, nfaces); fflush(stdout); cv::imwrite("minimal2.bmp", img); cv::imshow("stasm minimal2", img); cv::waitKey(); return 0; }
static PyObject* Py_lasterr( PyObject* self, PyObject* ) { const char* lasterr = stasm_lasterr(); PyObject* ret = Py_BuildValue("s", lasterr); return ret; }
static void ProcessImg( const char* imgpath) // in { Image img(cv::imread(imgpath, CV_LOAD_IMAGE_GRAYSCALE)); if (!img.data) Err("Cannot load %s", imgpath); if (!stasm_open_image((const char*)img.data, img.cols, img.rows, imgpath, multiface_g, minwidth_g)) Err("stasm_open_image failed: %s", stasm_lasterr()); CImage cimg; // color version of image if (writeimgs_g) // actually need the color image? cvtColor(img, cimg, CV_GRAY2BGR); int nfaces = 0; while (1) { if (trace_g && nfaces > 0 && multiface_g) stasm_printf("\n%d: ", nfaces); int foundface; float landmarks[2 * stasm_NLANDMARKS]; // x,y coords if (!stasm_search_auto(&foundface, landmarks)) Err("stasm_search_auto failed: %s", stasm_lasterr()); if (!foundface) break; // note break ProcessFace(cimg, landmarks, nfaces, Base(imgpath)); nfaces++; } if (trace_g) lprintf("\n"); if (writeimgs_g && nfaces) { // write as a bmp not as a jpg because don't want blurred shape lines char newpath[SLEN]; sprintf(newpath, "%s_stasm.bmp", Base(imgpath)); lprintf("%s ", newpath); if (!cv::imwrite(newpath, cimg)) Err("Could not write %s", newpath); } lprintf("%d face%s\n", nfaces, plural(nfaces)); }
int main(int argc, const char** argv) { stasm::CatchOpenCvErrs(); try { stasm::main1(argc, argv); } catch(...) { // a call was made to Err or a CV_Assert failed printf("\n%s\n", stasm_lasterr()); exit(1); } return 0; // success }
static PyObject* Py_open_image( PyObject* self, PyObject* args, PyObject* kwargs) { PyObject* img_obj; const char* debugpath = ""; int multiface = 0; int minwidth = 10; static const char* kwlist[] = { "image", "debugpath", "multiface", "minwidth", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|sii:open_image", const_cast<char**>(kwlist), &img_obj, &debugpath, &multiface, &minwidth)) return NULL; int width, height; const char* img_data = PyArray_to_image(img_obj, &width, &height); if (img_data == NULL) { PyErr_SetString(PyExc_TypeError, imarray_error); return NULL; } if (multiface != 0 && multiface != 1) { PyErr_SetString(PyExc_TypeError, multiface_error); return NULL; } if (minwidth < 1 || minwidth > 100) { PyErr_SetString(PyExc_ValueError, minwidth_error); return NULL; } if (!stasm_open_image(img_data, width, height, debugpath, multiface, minwidth)) { PyErr_SetString(StasmException, stasm_lasterr()); return NULL; } Py_RETURN_NONE; }
static PyObject* Py_search_auto( PyObject* self, PyObject* ) { int foundface; float* landmarks; landmarks = new float[stasm_NLANDMARKS * 2]; if (!stasm_search_auto(&foundface, landmarks)) { PyErr_SetString(StasmException, stasm_lasterr()); delete[] landmarks; return NULL; } int num_landmarks = foundface ? stasm_NLANDMARKS : 0; return landmarks_to_PyArray(landmarks, num_landmarks); }
static void main1(int argc, const char** argv) { OpenLogFile(); print_g = true; // want to be able to see lprintfs const bool old_trace = trace_g; if (!stasm_init("../data", 1 /*trace*/)) Err("stasm_init failed %s", stasm_lasterr()); trace_g = old_trace; ShapeFile sh; // contents of the shape file FILE* fitfile; // the fit file we will create Init(sh, fitfile, argc, argv); const clock_t start_time = clock(); ProcessShapes(sh, fitfile); lprintf("[MeanTimePerImg %.3f]\n", double(clock() - start_time) / (sh.nshapes_ * CLOCKS_PER_SEC)); fclose(fitfile); }
int main(int argc, char *argv[]) { std::string path = "../data/testface.jpg"; if (argc > 1) path = argv[1]; cv::Mat_<unsigned char> img(cv::imread(path, CV_LOAD_IMAGE_GRAYSCALE)); if (!img.data) { printf("Cannot load %s\n", path.c_str()); exit(1); } cv::resize(img, img, cv::Size(100, 100)); int foundface; float landmarks[2 * stasm_NLANDMARKS]; // x,y coords (note the 2) if (!stasm_search_single(&foundface, landmarks, (const char*)img.data, img.cols, img.rows, path.c_str(), "../data")) { printf("Error in stasm_search_single: %s\n", stasm_lasterr()); exit(1); } if (!foundface) printf("No face found in %s\n", path.c_str()); else { // draw the landmarks on the image as white dots (image is monochrome) stasm_force_points_into_image(landmarks, img.cols, img.rows); for (int i = 0; i < stasm_NLANDMARKS; i++) img(cvRound(landmarks[i*2+1]), cvRound(landmarks[i*2])) = 255; } cv::imwrite("minimal.bmp", img); cv::imshow("stasm minimal", img); cv::waitKey(); return 0; }
static PyObject* Py_search_pinned( PyObject* self, PyObject* args) { PyObject* pinned_obj; PyObject* img_obj; const char* debugpath = ""; if (!PyArg_ParseTuple(args, "OO|s:search_pinned", &pinned_obj, &img_obj, &debugpath)) return NULL; int width, height; const char* img_data = PyArray_to_image(img_obj, &width, &height); if (img_data == NULL) { PyErr_SetString(PyExc_TypeError, imarray_error); return NULL; } PyArrayObject* pinned_array = (PyArrayObject*)PyArray_FROM_OTF( pinned_obj, NPY_FLOAT, NPY_ARRAY_IN_ARRAY); if (pinned_array == NULL) return NULL; float* pinned = (float*)PyArray_DATA(pinned_array); float* landmarks = new float[stasm_NLANDMARKS * 2]; Py_DECREF(pinned_array); if (!stasm_search_pinned(landmarks, pinned, img_data, width, height, debugpath)) { PyErr_SetString(StasmException, stasm_lasterr()); delete[] landmarks; return NULL; } return landmarks_to_PyArray(landmarks, stasm_NLANDMARKS); }
static PyObject* Py_search_single( PyObject* self, PyObject* args, PyObject* kwargs) { PyObject* img_obj; const char* debugpath = ""; const char* datadir = PyStr_AS_STRING(datadir_default); static const char* kwlist[] = { "image", "debugpath", "datadir", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|ss:search_single", const_cast<char**>(kwlist), &img_obj, &debugpath, &datadir)) return NULL; int width, height; const char* img_data = PyArray_to_image(img_obj, &width, &height); if (img_data == NULL) { PyErr_SetString(PyExc_TypeError, imarray_error); return NULL; } int foundface; float* landmarks = new float[stasm_NLANDMARKS * 2]; if (!stasm_search_single(&foundface, landmarks, img_data, width, height, debugpath, datadir)) { PyErr_SetString(StasmException, stasm_lasterr()); delete[] landmarks; return NULL; } int landmarks_found = foundface ? stasm_NLANDMARKS : 0; return landmarks_to_PyArray(landmarks, landmarks_found); }
static void main1(int argc, const char** argv) { GetOptions(argc, argv); OpenLogFile(); // argc is now the number of images and argv is the image filenames const bool old_trace = trace_g; if (!stasm_init("../data", 1 /*trace*/)) Err("stasm_init failed %s", stasm_lasterr()); trace_g = old_trace; const int ndigits = int(floor(log10(double(argc)) + 1)); // for aligning for (int i_img = 0; i_img < argc; i_img++) { const char* const imgpath = argv[i_img]; if (argc > 1) lprintf("%*d ", ndigits, i_img); lprintf("%s: ", imgpath); ProcessImg(imgpath); } }
JNIEXPORT jintArray JNICALL Java_com_tuwien_snowwhite_FacialFeatureActivity_FindFaceLandmarks( JNIEnv* env, jobject, jstring jpath) { clock_t StartTime = clock(); jintArray arr = env->NewIntArray(2*stasm_NLANDMARKS); jint *out = env->GetIntArrayElements(arr, NULL); static const char * path; path = env->GetStringUTFChars( jpath , NULL ) ; cv::Mat_<unsigned char> img(cv::imread(path, CV_LOAD_IMAGE_GRAYSCALE)); if (!img.data) { __android_log_print(ANDROID_LOG_ERROR, "FacialFeatureActivity_FindFaceLandmarks", "Cannot load image file %s", path); out[0] = -1; out[1] = -1; img.release(); env->ReleaseIntArrayElements(arr, out, 0); return arr; } int foundface; float landmarks[2 * stasm_NLANDMARKS]; // x,y coords if (!stasm_search_single(&foundface, landmarks, (const char*)img.data, img.cols, img.rows, path, "/data/data/com.tuwien.snowwhite/app_stasmdata/")) { __android_log_print(ANDROID_LOG_ERROR, "FacialFeatureActivity_FindFaceLandmarks", "Error in stasm_search_single %s", stasm_lasterr()); out[0] = -2; out[1] = -2; img.release(); env->ReleaseIntArrayElements(arr, out, 0); return arr; } if (!foundface) { __android_log_print(ANDROID_LOG_WARN, "FacialFeatureActivity_FindFaceLandmarks", "no face found"); out[0] = -3; out[1] = -3; img.release(); env->ReleaseIntArrayElements(arr, out, 0); return arr; } else { for (int i = 0; i < stasm_NLANDMARKS; i++) { out[2*i] = cvRound(landmarks[2*i]); out[2*i+1] = cvRound(landmarks[2*i+1]); } } double TotalAsmTime = double(clock() - StartTime) / CLOCKS_PER_SEC; __android_log_print(ANDROID_LOG_INFO, "FacialFeatureActivity_FindFaceLandmarks", "Stasm Ver:%s Img:%dx%d ---> Time:%.3f secs.", stasm_VERSION, img.cols, img.rows, TotalAsmTime); img.release(); env->ReleaseIntArrayElements(arr, out, 0); return arr; }
int main(int argc, const char** argv) { if (argc != 5) Exit("Usage: test_stasm_lib MULTI MINWIDTH TRACE IMAGE"); const int multi = argv[1][0] - '0'; if (multi != 0 && multi != 1) Exit("Usage: test_stasm_lib MULTI MINWIDTH TRACE IMAGE, " "with MULTI 0 or 1, you have MULTI %s", argv[1]); int minwidth = -1; if (sscanf(argv[2], "%d", &minwidth) != 1 || minwidth < 1 || minwidth > 100) { Exit("Usage: test_stasm_lib MULTI MINWIDTH TRACE IMAGE with " "MINWIDTH 1 to 100, you have MINWIDTH %s", argv[2]); } const int trace = argv[3][0] - '0'; if (trace < 0 || trace > 1) Exit("Usage: test_stasm_lib MULTI MINWIDTH TRACE IMAGE, with TRACE 0 or 1"); if (!stasm_init("../data", trace)) Exit("stasm_init failed: %s", stasm_lasterr()); const char* path = argv[4]; // image name stasm_printf("Reading %s\n", path); const cv::Mat_<unsigned char> img(cv::imread(path, CV_LOAD_IMAGE_GRAYSCALE)); if (!img.data) // could not load image? Exit("Cannot load %s", path); cv::Mat_<unsigned char> outimg(img.clone()); if (!stasm_open_image((const char*)img.data, img.cols, img.rows, path, multi != 0, minwidth)) Exit("stasm_open_image failed: %s", stasm_lasterr()); // Test stasm_search_auto. // The min face size was set in the above stasm_open_image call. float landmarks[2 * stasm_NLANDMARKS]; // x,y coords int iface = 0; while (1) { stasm_printf("--- Auto Face %d ---\n", iface); int foundface; float estyaw; if (!stasm_search_auto_ext(&foundface, landmarks, &estyaw)) Exit("stasm_search_auto failed: %s", stasm_lasterr()); if (!foundface) { stasm_printf("No more faces\n"); break; // note break } char s[100]; sprintf(s, "\nFinal with auto init (estyaw %.0f)", estyaw); PrintLandmarks(landmarks, s); DrawLandmarks(outimg, landmarks); iface++; if (trace) stasm_printf("\n"); } imwrite("test_stasm_lib_auto.bmp", outimg); if (stasm_NLANDMARKS != 77) { stasm_printf( "Skipping pinned test because stasm_NLANDMARKS is %d not 77\n", stasm_NLANDMARKS); } else if (multi == 0 && minwidth == 25 && iface) { // Test stasm_search_pinned. A human user is not at hand, so gyp by using // points from the last face found above for our 5 start points stasm_printf("--- Pinned Face %d ---\n", iface); float pinned[2 * stasm_NLANDMARKS]; // x,y coords memset(pinned, 0, sizeof(pinned)); pinned[L_LEyeOuter*2] = landmarks[L_LEyeOuter*2] + 2; pinned[L_LEyeOuter*2+1] = landmarks[L_LEyeOuter*2+1]; pinned[L_REyeOuter*2] = landmarks[L_REyeOuter*2] - 2; pinned[L_REyeOuter*2+1] = landmarks[L_REyeOuter*2+1]; pinned[L_CNoseTip*2] = landmarks[L_CNoseTip*2]; pinned[L_CNoseTip*2+1] = landmarks[L_CNoseTip*2+1]; pinned[L_LMouthCorner*2] = landmarks[L_LMouthCorner*2]; pinned[L_LMouthCorner*2+1] = landmarks[L_LMouthCorner*2+1]; pinned[L_RMouthCorner*2] = landmarks[L_RMouthCorner*2]; pinned[L_RMouthCorner*2+1] = landmarks[L_RMouthCorner*2+1]; memset(landmarks, 0, sizeof(landmarks)); if (!stasm_search_pinned(landmarks, pinned, (const char*)img.data, img.cols, img.rows, path)) Exit("stasm_search_pinned failed: %s", stasm_lasterr()); PrintLandmarks(landmarks, "Final with pinned init"); outimg = img.clone(); DrawLandmarks(outimg, landmarks); imwrite("test_stasm_lib_pinned.bmp", outimg); // test stasm_convert_shape float newlandmarks[2 * stasm_NLANDMARKS]; // x,y coords memcpy(newlandmarks, landmarks, 2 * stasm_NLANDMARKS * sizeof(float)); stasm_convert_shape(newlandmarks, 68); PrintLandmarks(newlandmarks, "stasm77 to xm2vts"); #if 0 outimg = img.clone(); DrawLandmarks(outimg, newlandmarks, 68); imwrite("test_stasm_lib_68.bmp", outimg); #endif memcpy(newlandmarks, landmarks, 2 * stasm_NLANDMARKS * sizeof(float)); stasm_convert_shape(newlandmarks, 76); PrintLandmarks(newlandmarks, "stasm77 to stasm76"); #if 0 outimg = img.clone(); DrawLandmarks(outimg, newlandmarks, 76); imwrite("test_stasm_lib_76.bmp", outimg); #endif #if 0 memcpy(newlandmarks, landmarks, 2 * stasm_NLANDMARKS * sizeof(float)); stasm_convert_shape(newlandmarks, 22); PrintLandmarks(newlandmarks, "stasm77 to stasm22"); outimg = img.clone(); DrawLandmarks(outimg, newlandmarks, 22); imwrite("test_stasm_lib_22.bmp", outimg); memcpy(newlandmarks, landmarks, 2 * stasm_NLANDMARKS * sizeof(float)); stasm_convert_shape(newlandmarks, 20); PrintLandmarks(newlandmarks, "stasm77 to stasm20"); outimg = img.clone(); DrawLandmarks(outimg, newlandmarks, 20); imwrite("test_stasm_lib_20.bmp", outimg); #endif } return 0; // success }