Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

face example error error: undefined reference to `cv::FaceDetectorYN::create(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, #22557

Closed
gxxzs opened this issue Sep 23, 2022 · 2 comments
Labels
question (invalid tracker) ask questions and other "no action" items here: https://forum.opencv.org

Comments

@gxxzs
Copy link

gxxzs commented Sep 23, 2022

System information (version)

  • OpenCV => 4.5.4
  • Operating System / Platform => ubuntu 16.04+ros
  • Compiler => QT 59
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/objdetect/face.hpp>
#include<opencv2/core/cvstd.hpp>

#include <iostream>
using namespace cv;
using namespace std;
static
void visualize(Mat& input, int frame, Mat& faces, double fps, int thickness = 2)
{
    std::string fpsString = cv::format("FPS : %.2f", (float)fps);
    if (frame >= 0)
        cout << "Frame " << frame << ", ";
    cout << "FPS: " << fpsString << endl;
    for (int i = 0; i < faces.rows; i++)
    {
        // Print results
        cout << "Face " << i
             << ", top-left coordinates: (" << faces.at<float>(i, 0) << ", " << faces.at<float>(i, 1) << "), "
             << "box width: " << faces.at<float>(i, 2)  << ", box height: " << faces.at<float>(i, 3) << ", "
             << "score: " << cv::format("%.2f", faces.at<float>(i, 14))
             << endl;
        // Draw bounding box
        rectangle(input, Rect2i(int(faces.at<float>(i, 0)), int(faces.at<float>(i, 1)), int(faces.at<float>(i, 2)), int(faces.at<float>(i, 3))), Scalar(0, 255, 0), thickness);
        // Draw landmarks
        circle(input, Point2i(int(faces.at<float>(i, 4)), int(faces.at<float>(i, 5))), 2, Scalar(255, 0, 0), thickness);
        circle(input, Point2i(int(faces.at<float>(i, 6)), int(faces.at<float>(i, 7))), 2, Scalar(0, 0, 255), thickness);
        circle(input, Point2i(int(faces.at<float>(i, 8)), int(faces.at<float>(i, 9))), 2, Scalar(0, 255, 0), thickness);
        circle(input, Point2i(int(faces.at<float>(i, 10)), int(faces.at<float>(i, 11))), 2, Scalar(255, 0, 255), thickness);
        circle(input, Point2i(int(faces.at<float>(i, 12)), int(faces.at<float>(i, 13))), 2, Scalar(0, 255, 255), thickness);
    }
    putText(input, fpsString, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 2);
}
int main(int argc, char** argv)
{
    CommandLineParser parser(argc, argv,
        "{help  h           |            | Print this message}"
        "{image1 i1         |            | Path to the input image1. Omit for detecting through VideoCapture}"
        "{image2 i2         |            | Path to the input image2. When image1 and image2 parameters given then the program try to find a face on both images and runs face recognition algorithm}"
        "{video v           | 0          | Path to the input video}"
        "{scale sc          | 1.0        | Scale factor used to resize input video frames}"
        "{fd_model fd       | face_detection_yunet_2021dec.onnx| Path to the model. Download yunet.onnx in https://github.com/opencv/opencv_zoo/tree/master/models/face_detection_yunet}"
        "{fr_model fr       | face_recognition_sface_2021dec.onnx | Path to the face recognition model. Download the model at https://github.com/opencv/opencv_zoo/tree/master/models/face_recognition_sface}"
        "{score_threshold   | 0.9        | Filter out faces of score < score_threshold}"
        "{nms_threshold     | 0.3        | Suppress bounding boxes of iou >= nms_threshold}"
        "{top_k             | 5000       | Keep top_k bounding boxes before NMS}"
        "{save s            | false      | Set true to save results. This flag is invalid when using camera}"
    );
    if (parser.has("help"))
    {
        parser.printMessage();
        return 0;
    }
    cv::String fd_modelPath = parser.get<cv::String>("fd_model");
    cv::String fr_modelPath = parser.get<cv::String>("fr_model");
    float scoreThreshold = parser.get<float>("score_threshold");
    float nmsThreshold = parser.get<float>("nms_threshold");
    int topK = parser.get<int>("top_k");
    bool save = parser.get<bool>("save");
    float scale = parser.get<float>("scale");
    double cosine_similar_thresh = 0.363;
    double l2norm_similar_thresh = 1.128;
    // Initialize FaceDetectorYN
    Ptr<FaceDetectorYN> detector = FaceDetectorYN::create(fd_modelPath, " ", Size(320, 320), scoreThreshold, nmsThreshold, topK);
//    Ptr<FaceDetectorYN> detector;
    TickMeter tm;
    // If input is an image
    if (parser.has("image1"))
    {
        String input1 = parser.get<String>("image1");
        Mat image1 = imread(samples::findFile(input1));
        if (image1.empty())
        {
            std::cerr << "Cannot read image: " << input1 << std::endl;
            return 2;
        }
        int imageWidth = int(image1.cols * scale);
        int imageHeight = int(image1.rows * scale);
        resize(image1, image1, Size(imageWidth, imageHeight));
        tm.start();
        // Set input size before inference
        detector->setInputSize(image1.size());
        Mat faces1;
        detector->detect(image1, faces1);
        if (faces1.rows < 1)
        {
            std::cerr << "Cannot find a face in " << input1 << std::endl;
            return 1;
        }
        tm.stop();
        // Draw results on the input image
        visualize(image1, -1, faces1, tm.getFPS());
        // Save results if save is true
        if (save)
        {
            cout << "Saving result.jpg...\n";
            imwrite("result.jpg", image1);
        }
        // Visualize results
        imshow("image1", image1);
        pollKey();  // handle UI events to show content
        if (parser.has("image2"))
        {
            String input2 = parser.get<String>("image2");
            Mat image2 = imread(samples::findFile(input2));
            if (image2.empty())
            {
                std::cerr << "Cannot read image2: " << input2 << std::endl;
                return 2;
            }
            tm.reset();
            tm.start();
            detector->setInputSize(image2.size());
            Mat faces2;
            detector->detect(image2, faces2);
            if (faces2.rows < 1)
            {
                std::cerr << "Cannot find a face in " << input2 << std::endl;
                return 1;
            }
            tm.stop();
            visualize(image2, -1, faces2, tm.getFPS());
            if (save)
            {
                cout << "Saving result2.jpg...\n";
                imwrite("result2.jpg", image2);
            }
            imshow("image2", image2);
            pollKey();
            // Initialize FaceRecognizerSF
//            Ptr<FaceRecognizerSF> faceRecognizer = FaceRecognizerSF::create(fr_modelPath, "");
            Ptr<FaceRecognizerSF> faceRecognizer;
            // Aligning and cropping facial image through the first face of faces detected.
            Mat aligned_face1, aligned_face2;
            faceRecognizer->alignCrop(image1, faces1.row(0), aligned_face1);
            faceRecognizer->alignCrop(image2, faces2.row(0), aligned_face2);
            // Run feature extraction with given aligned_face
            Mat feature1, feature2;
            faceRecognizer->feature(aligned_face1, feature1);
            feature1 = feature1.clone();
            faceRecognizer->feature(aligned_face2, feature2);
            feature2 = feature2.clone();
            double cos_score = faceRecognizer->match(feature1, feature2, FaceRecognizerSF::DisType::FR_COSINE);
            double L2_score = faceRecognizer->match(feature1, feature2, FaceRecognizerSF::DisType::FR_NORM_L2);
            if (cos_score >= cosine_similar_thresh)
            {
                std::cout << "They have the same identity;";
            }
            else
            {
                std::cout << "They have different identities;";
            }
            std::cout << " Cosine Similarity: " << cos_score << ", threshold: " << cosine_similar_thresh << ". (higher value means higher similarity, max 1.0)\n";
            if (L2_score <= l2norm_similar_thresh)
            {
                std::cout << "They have the same identity;";
            }
            else
            {
                std::cout << "They have different identities.";
            }
            std::cout << " NormL2 Distance: " << L2_score << ", threshold: " << l2norm_similar_thresh << ". (lower value means higher similarity, min 0.0)\n";
        }
        cout << "Press any key to exit..." << endl;
        waitKey(0);
    }
//    else
//    {
//        int frameWidth, frameHeight;
//        VideoCapture capture;
//        std::string video = parser.get<string>("video");
//        if (video.size() == 1 && isdigit(video[0]))
//            capture.open(parser.get<int>("video"));
//        else
//            capture.open(samples::findFileOrKeep(video));  // keep GStreamer pipelines
//        if (capture.isOpened())
//        {
//            frameWidth = int(capture.get(CAP_PROP_FRAME_WIDTH) * scale);
//            frameHeight = int(capture.get(CAP_PROP_FRAME_HEIGHT) * scale);
//            cout << "Video " << video
//                << ": width=" << frameWidth
//                << ", height=" << frameHeight
//                << endl;
//        }
//        else
//        {
//            cout << "Could not initialize video capturing: " << video << "\n";
//            return 1;
//        }
//        detector->setInputSize(Size(frameWidth, frameHeight));
//        cout << "Press 'SPACE' to save frame, any other key to exit..." << endl;
//        int nFrame = 0;
//        for (;;)
//        {
//            // Get frame
//            Mat frame;
//            if (!capture.read(frame))
//            {
//                cerr << "Can't grab frame! Stop\n";
//                break;
//            }
//            resize(frame, frame, Size(frameWidth, frameHeight));
//            // Inference
//            Mat faces;
//            tm.start();
//            detector->detect(frame, faces);
//            tm.stop();
//            Mat result = frame.clone();
//            // Draw results on the input image
//            visualize(result, nFrame, faces, tm.getFPS());
//            // Visualize results
//            imshow("Live", result);
//            int key = waitKey(1);
//            bool saveFrame = save;
//            if (key == ' ')
//            {
//                saveFrame = true;
//                key = 0;  // handled
//            }
//            if (saveFrame)
//            {
//                std::string frame_name = cv::format("frame_%05d.png", nFrame);
//                std::string result_name = cv::format("result_%05d.jpg", nFrame);
//                cout << "Saving '" << frame_name << "' and '" << result_name << "' ...\n";
//                imwrite(frame_name, frame);
//                imwrite(result_name, result);
//            }
//            ++nFrame;
//            if (key > 0)
//                break;
//        }
//        cout << "Processed " << nFrame << " frames" << endl;
//    }
    cout << "Done." << endl;
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8.3)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project(dog_pose)

## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)

## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
  rospy
  roscpp
  sensor_msgs
  #std_msgs
  pcl_ros
  pcl_conversions
  cv_bridge
  sensor_msgs
  visualization_msgs
  tf
  cmake_modules
  geometry_msgs
  pcl_msgs
  kdl_parser

)



find_package(Boost REQUIRED)
find_package(Eigen REQUIRED)
find_package(octomap REQUIRED)

link_libraries(${OCTOMAP_LIBRARIES})


catkin_package(
    INCLUDE_DIRS
    CATKIN_DEPENDS roscpp rospy
    orocos_kdl
    kdl_parser
#    intera_core_msgs
    DEPENDS system_lib
    )
set(PCL_DIR "/home/zs/pcl-1.8/share/pcl-1.8")
find_package(PCL 1.8 REQUIRED)
#find_package(PCL REQUIRED)
 include_directories(
  ${PCL_INCLUDE_DIRS}
)
link_directories(
  ${PCL_LIBRARY_DIRS}
)

find_package(OpenCV PATHS /usr/local/opencv454/lib/cmake/opencv4)
include_directories(include ${catkin_INCLUDE_DIRS} /usr/local/opencv454/include/opencv4)
link_directories(/usr/local/opencv454/lib)
#find_package(OpenCV 4 REQUIRED)

#set(OpenCV_DIR /usr/local/opencv455/lib/cmake/OpenCV4)
#find_package(OpenCV REQUIRED)
#find_package(OpenCV 3 REQUIRED)
#include_directories(${OpenCV_INCLUDE_DIRS})
## System dependencies are found with CMake's conventions
# find_package(Boost REQUIRED COMPONENTS system)


## Uncomment this if the package has a setup.py. This macro ensures
## modules and global scripts declared therein get installed
## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
# catkin_python_setup()

################################################
## Declare ROS messages, services and actions ##
################################################

## To declare and build messages, services or actions from within this
## package, follow these steps:
## * Let MSG_DEP_SET be the set of packages whose message types you use in
##   your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
## * In the file package.xml:
##   * add a build_depend tag for "message_generation"
##   * add a build_depend and a run_depend tag for each package in MSG_DEP_SET
##   * If MSG_DEP_SET isn't empty the following dependency has been pulled in
##     but can be declared for certainty nonetheless:
##     * add a run_depend tag for "message_runtime"
## * In this file (CMakeLists.txt):
##   * add "message_generation" and every package in MSG_DEP_SET to
##     find_package(catkin REQUIRED COMPONENTS ...)
##   * add "message_runtime" and every package in MSG_DEP_SET to
##     catkin_package(CATKIN_DEPENDS ...)
##   * uncomment the add_*_files sections below as needed
##     and list every .msg/.srv/.action file to be processed
##   * uncomment the generate_messages entry below
##   * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)

## Generate messages in the 'msg' folder
# add_message_files(
#   FILES
#   Message1.msg
#   Message2.msg
# )

## Generate services in the 'srv' folder
# add_service_files(
#   FILES
#   Service1.srv
#   Service2.srv
# )

## Generate actions in the 'action' folder
# add_action_files(
#   FILES
#   Action1.action
#   Action2.action
# )

## Generate added messages and services with any dependencies listed here
# generate_messages(
#   DEPENDENCIES
#   std_msgs
# )

################################################
## Declare ROS dynamic reconfigure parameters ##
################################################

## To declare and build dynamic reconfigure parameters within this
## package, follow these steps:
## * In the file package.xml:
##   * add a build_depend and a run_depend tag for "dynamic_reconfigure"
## * In this file (CMakeLists.txt):
##   * add "dynamic_reconfigure" to
##     find_package(catkin REQUIRED COMPONENTS ...)
##   * uncomment the "generate_dynamic_reconfigure_options" section below
##     and list every .cfg file to be processed

## Generate dynamic reconfigure parameters in the 'cfg' folder
# generate_dynamic_reconfigure_options(
#   cfg/DynReconf1.cfg
#   cfg/DynReconf2.cfg
# )

###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if you package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
    CATKIN_DEPENDS pcl_conversions pcl_msgs pcl_ros sensor_msgs
  #  DEPENDS system_libCATKIN_DEPENDS
    DEPENDS
      Boost
      Eigen
      PCL
      orocos_kdl
      kdl_parser
      #kdl_parser
      DEPENDS system_lib
#  LIBRARIES project_1
#  CATKIN_DEPENDS rospy std_msgs
#  DEPENDS system_lib
)

###########
## Build ##
###########

## Specify additional locations of header files
## Your package locations should be listed before other locations
# include_directories(include)
include_directories(
  ${catkin_INCLUDE_DIRS}
#  /home/zs/pcl_ws/src/pcl_object_tracking/project_1/include
)

## Declare a C++ library
# add_library(project_1
#   src/${PROJECT_NAME}/project_1.cpp
# )

## Add cmake target dependencies of the library
## as an example, code may need to be generated before libraries
## either from message generation or dynamic reconfigure
# add_dependencies(project_1 ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

## Declare a C++ executable
# add_executable(project_1_node src/project_1_node.cpp)

## Add cmake target dependencies of the executable
## same as for the library above
# add_dependencies(project_1_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

## Specify libraries to link a library or executable target against
# target_link_libraries(project_1_node
#   ${catkin_LIBRARIES}
# )

#############
## Install ##
#############

# all install targets should use catkin DESTINATION variables
# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html

## Mark executable scripts (Python etc.) for installation
## in contrast to setup.py, you can choose the destination
# install(PROGRAMS
#   scripts/my_python_script
#   DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )

## Mark executables and/or libraries for installation
# install(TARGETS project_1 project_1_node
#   ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
#   LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
#   RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )

## Mark cpp header files for installation
# install(DIRECTORY include/${PROJECT_NAME}/
#   DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
#   FILES_MATCHING PATTERN "*.h"
#   PATTERN ".svn" EXCLUDE
# )

## Mark other files for installation (e.g. launch and bag files, etc.)
# install(FILES
#   # myfile1
#   # myfile2
#   DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
# )

#############
## Testing ##
#############


#add_executable(face_3d_pose src/face_3d_pose.cpp)
#target_link_libraries(face_3d_pose ${catkin_LIBRARIES}   ${OpenCV_LIBRARIES})

add_executable(face_detection src/face_detection.cpp)
target_link_libraries(face_detection ${catkin_LIBRARIES}   ${OpenCV_LIBRARIES}
    /usr/local/opencv454/lib/libopencv_highgui.so
    /usr/local/opencv454/lib/libopencv_core.so
    /usr/local/opencv454/lib/libopencv_imgproc.so
    /usr/local/opencv454/lib/libopencv_imgcodecs.so
    /usr/local/opencv454/lib/libopencv_dnn.so
    /usr/local/opencv454/lib/libopencv_dnn.so)

Error output

face_detection.cpp:67: error: undefined reference to `cv::FaceDetectorYN::create(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, std::_cxx11::basic_string<char, std::char_traits, std::allocator > const&, cv::Size const&, float, float, int, int, int)'

@fengyuentau
Copy link
Member

fengyuentau commented Sep 23, 2022

target_link_libraries(face_detection ${catkin_LIBRARIES} ${OpenCV_LIBRARIES}
/usr/local/opencv454/lib/libopencv_highgui.so
/usr/local/opencv454/lib/libopencv_core.so
/usr/local/opencv454/lib/libopencv_imgproc.so
/usr/local/opencv454/lib/libopencv_imgcodecs.so
/usr/local/opencv454/lib/libopencv_dnn.so
/usr/local/opencv454/lib/libopencv_dnn.so)

@gxxzs You need to check whether ${OpenCV_LIBRARIES} has libopencv_objdetect.so, and if it doesn't, please add /usr/local/opencv454/lib/libopencv_objdetect.so to the list of linking libraries.

@fengyuentau fengyuentau added question (invalid tracker) ask questions and other "no action" items here: https://forum.opencv.org and removed category: build/install category: objdetect labels Sep 23, 2022
@gxxzs
Copy link
Author

gxxzs commented Sep 26, 2022

target_link_libraries(face_detection catkinLIBRARIES{OpenCV_LIBRARIES}
/usr/local/opencv454/lib/libopencv_highgui.so
/usr/local/opencv454/lib/libopencv_core.so
/usr/local/opencv454/lib/libopencv_imgproc.so
/usr/local/opencv454/lib/libopencv_imgcodecs.so
/usr/local/opencv454/lib/libopencv_dnn.so
/usr/local/opencv454/lib/libopencv_dnn.so)

@gxxzs You need to check whether ${OpenCV_LIBRARIES} has libopencv_objdetect.so, and if it doesn't, please add /usr/local/opencv454/lib/libopencv_objdetect.so to the list of linking libraries.

/usr/local/opencv454/lib/libopencv_objdetect.so solve the problem. Thanks a lot.

@gxxzs gxxzs closed this as completed Sep 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question (invalid tracker) ask questions and other "no action" items here: https://forum.opencv.org
Projects
None yet
Development

No branches or pull requests

2 participants