forked from alyssaq/stasm_build
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstasm_util.cpp
More file actions
135 lines (121 loc) · 3.68 KB
/
stasm_util.cpp
File metadata and controls
135 lines (121 loc) · 3.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// command line utility to run stasm on an image
// Alyssa Quek 2015
#include <stdio.h>
#include <stdlib.h>
#include "opencv/highgui.h"
#include "stasm.h"
namespace stasm {
static int showimg_g = false; // -s flag
static int nlandmarks_g = stasm_NLANDMARKS; // -n flag
static bool csv_g; // -c flag
static const char* datafolder_g;
//-----------------------------------------------------------------------------
static void GetOptions(int &argc, const char** &argv) {
static const char* const usage =
"./stasm_util [FLAGS] <image_path>\n"
"\n"
"Prints (x, y) landmarks to terminal\n"
"\n"
"Example: ./stasm_util -f data face.jpg\n"
"\n"
"Flags:\n"
" -f folder to xml data\n"
" -s show image with landmarks\n"
" -n N save as 77, 76, 68, 22, 20, or 17 point shape\n"
" -? help\n"
"\n";
if (argc < 2) {
Err("No image. Use stasm -? for help.");
}
while (--argc > 0 && (*++argv)[0] == '-') {
if ((*argv + 1)[1]) {
Err("Invalid argument -%s (there must be a space after -%c). "
"Use stasm -? for help.",
*argv + 1, (*argv + 1)[0]);
}
switch ((*argv + 1)[0]) {
case 's':
showimg_g = true;
break;
case 'f':
if (argc < 3)
Err("-f argument must be followed by folder path. For example -f data/");
argc--;
argv++;
datafolder_g = *argv;
break;
case 'n':
if (argc < 3)
Err("-n argument must be followed by NLANDMARKS. For example -n 68");
argc--;
argv++;
nlandmarks_g = -1;
if (1 != sscanf(*argv, "%d", &nlandmarks_g) || nlandmarks_g < 1)
Err("-n argument must be followed by NLANDMARKS. For example -n 68");
break;
case '?':
printf("%s", usage);
exit(1);
default:
Err("Invalid argument -%s. Use stasm -? for help.", *argv + 1);
break;
}
}
if (argc < 1) {
Err("No image. Use stasm -? for help.");
}
}
static void ProcessImg(const char* imgpath) {
cv::Mat_<unsigned char> img(cv::imread(imgpath, CV_LOAD_IMAGE_GRAYSCALE));
if (!img.data) {
printf("Cannot load %s\n", imgpath);
exit(1);
}
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, imgpath, datafolder_g)) {
printf("Error in stasm_search_single: %s\n", stasm_lasterr());
exit(1);
}
if (!foundface) {
printf("No face found in %s\n", imgpath);
} else {
// draw the landmarks on the image as white dots (image is monochrome)
stasm_force_points_into_image(landmarks, img.cols, img.rows);
//printf("Num points: %d \n", stasm_NLANDMARKS);
for (int i = 0; i < stasm_NLANDMARKS; i++) {
printf("%d %d\n", cvRound(landmarks[i*2]), cvRound(landmarks[i*2+1]));
if (showimg_g) {
img(cvRound(landmarks[i*2+1]), cvRound(landmarks[i*2])) = 255;
}
}
}
if (showimg_g) {
cv::imshow("stasm minimal", img);
cv::waitKey();
}
}
static void main1(int argc, const char** argv) {
GetOptions(argc, argv);
// argc is now the number of images and argv is the image filenames
if (!stasm_init(datafolder_g, 0 /*trace*/)) {
Err("stasm_init failed %s", stasm_lasterr());
}
for (int i_img = 0; i_img < argc; i_img++) {
const char* const imgpath = argv[i_img];
ProcessImg(imgpath);
}
}
} // namespace stasm
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
}