Background
FDDB, nearly 20 years old codes (even with a April 1, 2020 updated Gnuplot scripts for generating the ROC curves), should be run just fine - Not on the MAC!
Build and Errors
Build is easy, really.
- Choose Mac because only Makefile available with
pkg-config
for setting up OpenCV paths and libraries - Should be easy to build on Windows anyway, either by manually specify the OpenCV path/libs, or create a simple CMakefile then build it
ERROR: Illegal instruction: 4
What is the “Illegal Instruction: 4”
The “illegal instruction” message is simply telling you that your binaries contain instructions the version of the OS that you are attempting to run them under does not understand. I can’t give you the precise meaning of 4 but I expect that is internal to Apple.
REASON
To do with the warning messages in below during compilation
RegionsSingleImage.cpp:38:2: warning: delete called on 'Region' that is abstract but has non-virtual destructor
[-Wdelete-non-virtual-dtor]
delete(list->at(i));
^
1 warning generated.
evaluate.cpp:320:5: warning: delete called on 'RegionsSingleImage' that is abstract but has non-virtual destructor
[-Wdelete-non-virtual-dtor]
delete(annot);
^
evaluate.cpp:321:5: warning: delete called on 'RegionsSingleImage' that is abstract but has non-virtual destructor
[-Wdelete-non-virtual-dtor]
delete(det);
^
2 warnings generated.
Interfaces in C++ (Abstract Classes
What does ‘has virtual method … but non-virtual destructor’ warning mean during C++ compilation?
If a class has a virtual method, that means you want other classes to inherit from it. These classes could be destroyed through a base-class-reference or pointer, but this would only work if the base-class has a virtual destructor. If you have a class that is supposed to be usable polymorphically, it should also be deletable polymorphically.
When should your destructor be virtual? [duplicate]
When delete a derived class object with no virtual destructor, it is undefined behavior , apparently modern macOS and build tools are more strict with the rules
浅谈 C++ 中的 new/delete 和 new[]/delete[]
Solution
add TWO ‘virtual’ keywords
virtual ~Region();
inRegion.hpp
virtual ~RegionsSingleImage();
inRegionsSingleImage.hpp
Generate detection results
def get_img_relative_path():
"""
:return: ['2002/08/11/big/img_344', '2002/08/02/big/img_473', ......]
"""
f_name = 'E:/face_rec/face__det_rec_code/face_det/FDDB-folds/all_img_files.txt'
lst_name = open(f_name).read().split('\n')
return lst_name
def write_lines_to_txt(lst):
# lst = ['line1', 'line2', 'line3']
f_path = 'fddb_rect_ret.txt'
with open(f_path, 'w') as fp:
for line in lst:
fp.write("%s\n" % line)
# For example use opencv to face detection
def detect_face_lst(img):
"""
:param img: opencv image
:return: face rectangles [[x, y, w, h], ..........]
"""
m_path = 'D:/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml'
face_cascade = cv2.CascadeClassifier(m_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
return faces
def generate_fddb_ret():
# The directory from which we get the test images from FDDB
img_base_dir = 'E:/face_rec/face__det_rec_code/face_det/originalPics/'
# All the images relative path, like '['2002/08/11/big/img_344', '2002/08/02/big/img_473', ......]'
lst_img_name = get_img_relative_path()
# Store detect result, like:
# ['2002/08/11/big/img_344', '1', '10 10 50 50 1', .............]
lst_write2_fddb_ret = []
try:
for img_name in lst_img_name:
img_full_name = img_base_dir + img_name + '.jpg'
img = cv2.imread(img_full_name)
if img == None:
print 'error %s not exists, can not generate complete fddb evaluate file' % img_full_name
return -1
lst_face_rect = detect_face_lst(img)
# append img name like '2002/08/11/big/img_344'
lst_write2_fddb_ret.append(img_name)
face_num = len(lst_face_rect)
# append face num, note if no face 0 should be append
lst_write2_fddb_ret.append(str(face_num))
if face_num > 0:
# append each face rectangle x y w h score
for face_rect in lst_face_rect:
# append face rectangle x, y, w, h score
# note: opencv hava no confidence so use 1 here
s_rect = " ".join(str(item) for item in face_rect) + " 1"
lst_write2_fddb_ret.append(s_rect)
except Exception as e:
print 'error %s , can not generate complete fddb evaluate file' % e
return -1
# Write all the result to txt for FDDB evaluation
write_lines_to_txt(lst_write2_fddb_ret)