sfzhang15 / FaceBoxes

FaceBoxes: A CPU Real-time Face Detector with High Accuracy, IJCB, 2017
Apache License 2.0
591 stars 171 forks source link

The output of CPP code is weird #33

Closed ardeal closed 5 years ago

ardeal commented 5 years ago

Hi Dr. Zhang,

A few days ago, I could run faceboxes model on pycaffe correctly. The face detection result of the algorithms is good as well.


I followed the example code in SSD(https://github.com/weiliu89/caffe/blob/ssd/examples/ssd/ssd_detect.cpp) to call your faceboxes mode using cpp in Caffe.

The code could be run correctly, but the output of algorithms seems to be weird: 1) for some images, the output is very good(The same as that in pycaffe). 2) for some images, the output is weird. Please check the following output: For those abnormal images, the score is very small and the boxes is not aligned as well. For those normal images, the score and boxes are both normal.


I used the same network file and weights file downloaded from your code, and I used the same code as pycaffe.

The only difference is that I use CPP to call the model.

Why are the output of some images not correct? Do you have any idea about the issue?

image

image

image

image

sfzhang15 commented 5 years ago

@ardeal Since I have not done it, I am not sure what is going on here. There is another issue in Chinese about the same problem, if there is a solution, I will respond to you in time.

ardeal commented 5 years ago

Many thanks for your reply! Dr. Zhang!

sfzhang15 commented 5 years ago

@ardeal There is a solution in this issue in Chineses that you can try to solve your problem:

The model loading function under windows always copies only the first layer of the trained model, i.e., the function bool ReadProtoFromBinaryFile(const char* filename, Message* proto) in the io.cpp file. In this function, the default call on Windows is int fd = open(filename, O_RDONLY), which does not read the model file in binary mode, causing incorrect loading. The modification is as following: image

ardeal commented 5 years ago

Hi Dr. Zhang,

Many thanks for your help!

I have found out the root cause of this issue which is not related with Windows or Linux.

I should re-set mean value once the size of image is changed:

int init_meanvalue(cv::Mat & img)
{
    input_geometry_ = cv::Size(img.cols, img.rows);
    SetMean(pFaceBoxConfig->mean_file, pFaceBoxConfig->mean_value);
    return 1;
}

This is different from Python interface which uses caffe.io.load_image to load image. I suspect the Python interface might resize or pad the image to a unified size.

Thanks and Best Regards, Ardeal

ardeal commented 5 years ago

Hi Dr. Zhang,

Many thanks for your help!

I have found out the root cause of this issue which is not related with Windows or Linux.

I should re-set mean value once the size of image is changed:

int init_meanvalue(cv::Mat & img)
{
    input_geometry_ = cv::Size(img.cols, img.rows);
    SetMean(pFaceBoxConfig->mean_file, pFaceBoxConfig->mean_value);
    return 1;
}

This is different from Python interface which uses caffe.io.load_image to load image. I suspect the Python interface might resize or pad the image to a unified size.

Thanks and Best Regards, Ardeal

sfzhang15 commented 5 years ago

@ardeal Got it. For python, there are three mean values for R/G/B channels, respectively. No matter how large the image is, the three value are used. For C++, you may need to build a mean metric whose size is the same as the one of the input image.