ncnn仅使用opencv实现人脸检测和人脸特征提取

人脸检测基于opencv-CascadeClassifier, 特征提取使用的是自己insightface的mxnet转化为ncnn的模型。

,cpp 文件:

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <time.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/objdetect/objdetect.hpp"

#include "net.h"
using namespace std;

//print tensor
void pretty_print(const ncnn::Mat& m)
{
    int count = 0;
    for (int q=0; q<m.c; q++)
    {
        const float* ptr = m.channel(q);
        for (int y=0; y<m.h; y++)
        {
            for (int x=0; x<m.w; x++)
            {
                printf("%f ", ptr[x]);
                count++;
            }
            ptr += m.w;
            printf("\n");
        }
        printf("------------------------\n");
        printf("%d\n",count);
    }
}

//main
int main(int argc, char** argv){
	
	// 定义输入格式
	if (argc != 2) {
		fprintf(stderr, "input error\n");
		return -2;
	}  
	//string path = argv[1];
  
	//定义级联分类器
	cv::CascadeClassifier face_detector;
	//加在分类器
	face_detector.load("haarcascade_frontalface_alt2.xml");
	//判断分类器是否加载成功
	if (face_detector.empty())
	{
		std::cerr << "load detector failed!!!" << std::endl;
		return -1;
	}
	cv::Size original_size = face_detector.getOriginalWindowSize();
	
	// 导入模型
	ncnn::Net net;
    printf("net init\n");
    //net.opt.num_threads=1;
    net.load_param("model-symbol.param");
    printf("load model param\n");
    net.load_model("model-symbol.bin");
    printf("load model bin\n");
	
	
	
	clock_t start, finish;
	
	string img_path = argv[1];
    cv::Mat img = cv::imread(img_path, cv::IMREAD_COLOR);
    
	cv::Mat image_gray;
	cv::cvtColor(img, image_gray, cv::COLOR_BGR2GRAY);
	
	//用于保存检测到的目标窗口
	std::vector<cv::Rect> dets;
	//进行多尺度人脸检测
	face_detector.detectMultiScale(image_gray, dets, 1.1, 3, 0 | cv::CASCADE_SCALE_IMAGE, original_size);
 
	// 获取所有人脸
	/**
	for (size_t i = 0; i < faces.size(); i++)
	{
		
		cv::rectangle(image, faces[i], cv::Scalar(0, 0, 255), 2, 8, 0);
	}
	**/
	
	// 获取最大人脸
	cv::Rect R;
	int Max = 0;
    int area = 0;
    for (size_t t = 0; t < dets.size(); ++t)
    {      
      if (area < dets[t].width * dets[t].height)
      {
        area = dets[t].width * dets[t].height;
        Max = t;
      }
    }
    R.x = dets[Max].x;
    R.y = dets[Max].y;
    R.width = dets[Max].width;
    R.height = dets[Max].height;
	
	// max_face 最大人脸
	cv::Mat max_face = img(R);
	
	// 显示出来最大人脸
	// cv::imshow("detect result", max_face);
	// cv::waitKey(0);
	
	// resize图片为模型指定的输入
	cv::Mat img2;
	int input_width = 112;//转onnx时指定的输入大小
    int input_height = 112;
    // resize
    printf("---1111---\n");
    cv::resize(max_face, img2, cv::Size(input_width, input_height));
    printf("---cv ok---\n");
    // load model
    
    // 把opencv的mat转换成ncnn的mat
    ncnn::Mat input = ncnn::Mat::from_pixels(img2.data, ncnn::Mat::PIXEL_BGR, img2.cols, img2.rows);
    printf("convert ncnn\n");
    // ncnn froward
    
	// 模型前向传播
    printf("net forward\n");
	for(int i=0; i<1000; i++){
		start = clock();
		ncnn::Extractor extractor = net.create_extractor();
		extractor.input("data", input);
		ncnn::Mat output0;//取决于模型的输出有几个
		extractor.extract("fc1", output0);
		finish = clock();
		double duration = (double)(finish - start) / CLOCKS_PER_SEC;
		printf( "%.4f seconds\n", duration );
		//pretty_print(output0);
	}
	
	
    printf("get output0\n");
    
	// 打印 tensor
    // pretty_print(output1);
 
    cout<<"done"<<endl;
    return 0;
}

 

CMakeLists.txt 配置(将dlib相关的删除,没有依赖dlib)

macro(ncnn_add_example name)
    add_executable(${name} ${name}.cpp)
    # add_library(${name} SHARED ${name}.cpp)
    target_include_directories(${name} PRIVATE ${OpenCV_INCLUDE_DIRS} ${dlib_INCLUDE_DIRS} )
    target_link_libraries(${name} PRIVATE ncnn ${OpenCV_LIBS} ${dlib_LIBRARIES})
    
    # target_include_directories(${name} PRIVATE ${dlib_INCLUDE_DIRS})
    # target_link_libraries(${name} PRIVATE ncnn ${dlib_LIBRARIES} )
    # add test to a virtual project group
    # set_target_properties(dlib PROPERTIES POSITION_INDEPENDENT_CODE ON)
    set_property(TARGET ${name} PROPERTY FOLDER "examples")
endmacro()

# find_package(dlib REQUIRED) 
# include_directories(${dlib_INCLUDE_DIRS}) 
# add_executable(${PROJECT_NAME} ${SRC_LIST})
# target_link_libraries(${PROJECT_NAME} ${dlib_LIBRARIES})
# add_subdirectory(/home/zb/zhangr/opencv-2.4.9 ${PROJECT_NAME}/opencv_build)
add_subdirectory(/home/zb/zhangr/dlib dlib_build)
#add_executable(dlib1 dlib1.cpp)
# Finally, you need to tell CMake that this program, assignment_learning_ex,
# depends on dlib.  You do that with this statement:
#target_link_libraries(dlib1 dlib::dlib)
#set_property(TARGET dlib1 PROPERTY FOLDER "examples")

#add_executable(dlib2 dlib2.cpp)
#target_link_libraries(dlib2 dlib::dlib)
#set_property(TARGET dlib2 PROPERTY FOLDER "examples")


find_package(OpenCV QUIET COMPONENTS opencv_world objdetect)

find_package(dlib REQUIRED) 

#add_executable(main2 main2.cpp)
#target_include_directories(main2 PRIVATE ${OpenCV_INCLUDE_DIRS})
#target_link_libraries(main2  ncnn ${OpenCV_LIBS} dlib::dlib)
#set_property(TARGET main2 PROPERTY FOLDER "examples")

# for opencv 2.4 on ubuntu 16.04, there is no opencv_world but OpenCV_FOUND will be TRUE
if("${OpenCV_LIBS}" STREQUAL "")
    set(OpenCV_FOUND FALSE)
endif()
if(NOT OpenCV_FOUND)
    find_package(OpenCV QUIET COMPONENTS core highgui imgproc imgcodecs videoio)
endif()
if(NOT OpenCV_FOUND)
    find_package(OpenCV QUIET COMPONENTS core highgui imgproc)
endif()

if(OpenCV_FOUND)
    message(STATUS "OpenCV library: ${OpenCV_INSTALL_PATH}")
    message(STATUS "    version: ${OpenCV_VERSION}")
    message(STATUS "    libraries: ${OpenCV_LIBS}")
    message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")
    
    if(${OpenCV_VERSION_MAJOR} GREATER 3)
        set(CMAKE_CXX_STANDARD 11)
    endif()
    include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../src)
    include_directories(${CMAKE_CURRENT_BINARY_DIR}/../src)

    ncnn_add_example(squeezenet)
    ncnn_add_example(squeezenet_c_api)
    ncnn_add_example(fasterrcnn)
    ncnn_add_example(rfcn)
    ncnn_add_example(yolov2)
    ncnn_add_example(yolov3)
    ncnn_add_example(yolov4)
    ncnn_add_example(mobilenetv2ssdlite)
    ncnn_add_example(mobilenetssd)
    ncnn_add_example(squeezenetssd)
    ncnn_add_example(shufflenetv2)
    ncnn_add_example(peleenetssd_seg)
    ncnn_add_example(simplepose)
    ncnn_add_example(retinaface)
    ncnn_add_example(yolact)
    ncnn_add_example(main)
    ncnn_add_example(main1)
    ncnn_add_example(main2)
    ncnn_add_example(main3)
    ncnn_add_example(Harr)
    ncnn_add_example(only_opencv)
else()
    message(WARNING "OpenCV not found, examples won't be built")
endif()

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值