mirror of
https://github.com/opencv/opencv_contrib.git
synced 2025-10-18 17:24:28 +08:00
face: fix mace code / test
This commit is contained in:
@@ -204,52 +204,18 @@ struct MACEImpl CV_FINAL : MACE {
|
|||||||
minMaxLoc(re, &m1, &M1, 0, 0);
|
minMaxLoc(re, &m1, &M1, 0, 0);
|
||||||
double peakCorrPlaneEnergy = M1 / sqrt(sum(re)[0]);
|
double peakCorrPlaneEnergy = M1 / sqrt(sum(re)[0]);
|
||||||
re -= m1;
|
re -= m1;
|
||||||
double value=0;
|
|
||||||
double num=0;
|
// circle mask for the sidelobe area
|
||||||
int rad_1=int(floor((double)(45.0/64.0)*(double)IMGSIZE));
|
Mat mask(IMGSIZE_2X, IMGSIZE_2X, CV_8U, Scalar(0));
|
||||||
int rad_2=int(floor((double)(27.0/64.0)*(double)IMGSIZE));
|
int rad_1 = int(floor((double)(45.0/64.0)*(double)IMGSIZE));
|
||||||
// cache a few pow's and sqrts
|
int rad_2 = int(floor((double)(27.0/64.0)*(double)IMGSIZE));
|
||||||
std::vector<double> r2(IMGSIZE_2X);
|
circle(mask, Point(IMGSIZE,IMGSIZE), rad_1, Scalar(255), -1);
|
||||||
Mat_<double> radtab(IMGSIZE_2X,IMGSIZE_2X);
|
circle(mask, Point(IMGSIZE,IMGSIZE), rad_2, Scalar(0), -1);
|
||||||
for (int l=0; l<IMGSIZE_2X; l++) {
|
|
||||||
r2[l] = (l-IMGSIZE) * (l-IMGSIZE);
|
Scalar mean, dev;
|
||||||
}
|
meanStdDev(re, mean, dev, mask);
|
||||||
for (int l=0; l<IMGSIZE_2X; l++) {
|
double peak = re(IMGSIZE, IMGSIZE);
|
||||||
for (int m=l+1; m<IMGSIZE_2X; m++) {
|
double peakToSideLobeRatio = (peak - mean[0]) / dev[0];
|
||||||
double rad = sqrt(r2[m] + r2[l]);
|
|
||||||
radtab(l,m) = radtab(m,l) = rad;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// mean of the sidelobe area:
|
|
||||||
for (int l=0; l<IMGSIZE_2X; l++) {
|
|
||||||
for (int m=0; m<IMGSIZE_2X; m++) {
|
|
||||||
double rad = radtab(l,m);
|
|
||||||
if (rad < rad_1) {
|
|
||||||
if (rad > rad_2) {
|
|
||||||
value += re(l,m);
|
|
||||||
num++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
value /= num;
|
|
||||||
// normalize it
|
|
||||||
double std2=0;
|
|
||||||
for (int l=0; l<IMGSIZE_2X; l++) {
|
|
||||||
for (int m=0; m<IMGSIZE_2X; m++) {
|
|
||||||
double rad = radtab(l,m);
|
|
||||||
if (rad < rad_1) {
|
|
||||||
if (rad > rad_2) {
|
|
||||||
double d = (value - re(l,m));
|
|
||||||
std2 += d * d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std2 /= num;
|
|
||||||
std2 = sqrt(std2);
|
|
||||||
double sca = re(IMGSIZE, IMGSIZE);
|
|
||||||
double peakToSideLobeRatio = (sca - value) / std2;
|
|
||||||
|
|
||||||
return 100.0 * peakToSideLobeRatio * peakCorrPlaneEnergy;
|
return 100.0 * peakToSideLobeRatio * peakCorrPlaneEnergy;
|
||||||
}
|
}
|
||||||
|
@@ -7,134 +7,62 @@
|
|||||||
|
|
||||||
namespace opencv_test { namespace {
|
namespace opencv_test { namespace {
|
||||||
|
|
||||||
//
|
const string FACE_DIR = "face";
|
||||||
// train on one person, and test against the other
|
const int WINDOW_SIZE = 64;
|
||||||
//
|
|
||||||
#define TESTSET_NAMES testing::Values("david","dudek")
|
|
||||||
|
|
||||||
const string TRACKING_DIR = "tracking";
|
|
||||||
const string FOLDER_IMG = "data";
|
|
||||||
|
|
||||||
|
|
||||||
class MaceTest
|
class MaceTest
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MaceTest(string _video, bool salt);
|
MaceTest(bool salt);
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
vector<Rect> boxes(const string &fn);
|
|
||||||
vector<Mat> samples(const string &name, int N,int off=0);
|
|
||||||
int found(const string &vid);
|
|
||||||
|
|
||||||
Ptr<MACE> mace;
|
Ptr<MACE> mace;
|
||||||
|
|
||||||
string video; // train
|
|
||||||
string vidA; // test
|
|
||||||
|
|
||||||
int nSampsTest;
|
|
||||||
int nSampsTrain;
|
|
||||||
int nStep;
|
|
||||||
bool salt;
|
bool salt;
|
||||||
};
|
};
|
||||||
|
|
||||||
MaceTest::MaceTest(string _video, bool use_salt)
|
MaceTest::MaceTest(bool use_salt)
|
||||||
{
|
{
|
||||||
int Z = 64; // window size
|
mace = MACE::create(WINDOW_SIZE);
|
||||||
mace = MACE::create(Z);
|
|
||||||
|
|
||||||
video = _video;
|
|
||||||
if (video=="david") { vidA="dudek"; }
|
|
||||||
if (video=="dudek") { vidA="david"; }
|
|
||||||
|
|
||||||
nStep = 2;
|
|
||||||
nSampsTest = 5;
|
|
||||||
nSampsTrain = 35;
|
|
||||||
salt = use_salt;
|
salt = use_salt;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Rect> MaceTest::boxes(const string &fn)
|
|
||||||
{
|
|
||||||
std::ifstream in(fn.c_str());
|
|
||||||
int x,y,w,h;
|
|
||||||
char sep;
|
|
||||||
vector<Rect> _boxes;
|
|
||||||
while (in.good() && (in >> x >> sep >> y >> sep >> w >> sep >> h))
|
|
||||||
{
|
|
||||||
_boxes.push_back( Rect(x,y,w,h) );
|
|
||||||
}
|
|
||||||
return _boxes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaceTest::run()
|
void MaceTest::run()
|
||||||
{
|
{
|
||||||
vector<Mat> sam_train = samples(video, nSampsTrain, 0);
|
Rect david1 (125,66,58,56);
|
||||||
if (salt) mace->salt(video); // "owner's" salt with "two factor"
|
Rect david2 (132,69,73,74);
|
||||||
|
Rect detect (199,124,256,274);
|
||||||
|
string folder = cvtest::TS::ptr()->get_data_path() + FACE_DIR;
|
||||||
|
Mat train = imread(folder + "/david2.jpg", 0);
|
||||||
|
Mat tst_p = imread(folder + "/david1.jpg", 0);
|
||||||
|
Mat tst_n = imread(folder + "/detect.jpg", 0);
|
||||||
|
vector<Mat> sam_train;
|
||||||
|
sam_train.push_back( train(Rect(132,69,73,74)) );
|
||||||
|
sam_train.push_back( train(Rect(130,69,73,72)) );
|
||||||
|
sam_train.push_back( train(Rect(134,67,73,74)) );
|
||||||
|
sam_train.push_back( tst_p(Rect(125,66,58,56)) );
|
||||||
|
sam_train.push_back( tst_p(Rect(123,67,55,58)) );
|
||||||
|
sam_train.push_back( tst_p(Rect(125,65,58,60)) );
|
||||||
|
|
||||||
|
if (salt) mace->salt("it's david"); // "owner's" salt
|
||||||
mace->train(sam_train);
|
mace->train(sam_train);
|
||||||
int self_ok = found(video);
|
bool self_ok = mace->same(train(david2));
|
||||||
if (salt) mace->salt(vidA); // "other's" salt
|
if (salt) mace->salt("this is a test"); // "other's" salt
|
||||||
int false_A = found(vidA);
|
bool false_A = mace->same(tst_n(detect));
|
||||||
ASSERT_GE(self_ok, nSampsTest/2); // it may miss positives
|
ASSERT_TRUE(self_ok);
|
||||||
ASSERT_EQ(false_A, 0); // but *absolutely* no false positives allowed.
|
ASSERT_FALSE(false_A);
|
||||||
}
|
|
||||||
|
|
||||||
int MaceTest::found(const string &vid)
|
|
||||||
{
|
|
||||||
vector<Mat> sam_test = samples(vid, nSampsTest, (1+nStep*nSampsTrain));
|
|
||||||
int hits = 0;
|
|
||||||
for (size_t i=0; i<sam_test.size(); i++)
|
|
||||||
{
|
|
||||||
hits += mace->same(sam_test[i]);
|
|
||||||
}
|
|
||||||
return hits;
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<Mat> MaceTest::samples(const string &name, int N, int off)
|
|
||||||
{
|
|
||||||
string folder = cvtest::TS::ptr()->get_data_path() + TRACKING_DIR + "/" + name;
|
|
||||||
string vid = folder + "/" + FOLDER_IMG + "/" + name + ".webm";
|
|
||||||
string anno = folder + "/gt.txt";
|
|
||||||
vector<Rect> bb = boxes(anno);
|
|
||||||
int startFrame = (name=="david") ? 300 : 0;
|
|
||||||
VideoCapture c;
|
|
||||||
EXPECT_TRUE(c.open(vid));
|
|
||||||
vector<Mat> samps;
|
|
||||||
while (samps.size() < size_t(N))
|
|
||||||
{
|
|
||||||
int frameNo = startFrame + off;
|
|
||||||
c.set(CAP_PROP_POS_FRAMES, frameNo);
|
|
||||||
Mat frame;
|
|
||||||
c >> frame;
|
|
||||||
Rect r = bb[off];
|
|
||||||
off += nStep;
|
|
||||||
samps.push_back(frame(r));
|
|
||||||
}
|
|
||||||
c.release();
|
|
||||||
return samps;
|
|
||||||
}
|
|
||||||
|
|
||||||
//[TESTDATA]
|
|
||||||
PARAM_TEST_CASE(MACE_, string)
|
|
||||||
{
|
|
||||||
string dataset;
|
|
||||||
virtual void SetUp()
|
|
||||||
{
|
|
||||||
dataset = GET_PARAM(0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
TEST_P(MACE_, unsalted)
|
|
||||||
{
|
|
||||||
MaceTest test(dataset, false); test.run();
|
|
||||||
}
|
|
||||||
TEST_P(MACE_, salted)
|
|
||||||
{
|
|
||||||
MaceTest test(dataset, true); test.run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(Face, MACE_, TESTSET_NAMES);
|
TEST(MACE_, unsalted)
|
||||||
|
{
|
||||||
|
MaceTest test(false); test.run();
|
||||||
|
}
|
||||||
|
TEST(MACE_, salted)
|
||||||
|
{
|
||||||
|
MaceTest test(true); test.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}} // namespace
|
}} // namespace
|
||||||
|
Reference in New Issue
Block a user