人臉位置標識程序

最近學習R-CNN,好像訓練的時候需要物體位置作爲標籤

Opencv + libfacedetection

#include <corecrt_io.h>

#include <iostream>
#include <string>
#include <fstream>
#include <vector>

#include <opencv2/opencv.hpp>
#include "facedetect-dll.h"

#pragma comment(lib,"libfacedetect.lib")
#pragma comment(lib,"libfacedetect-x64.lib")

#if _DEBUG
#pragma comment(lib,"opencv_world410d.lib")
#else
#pragma comment(lib,"opencv_world410.lib")
#endif

using namespace std;
using namespace cv;
#define DETECT_BUFFER_SIZE 0x20000

enum operator_type
{
	frontal = 0,
	frontal_surveillance,
	multiview,
	multiview_reinforce,
	number
};

struct target_info
{
	int pos_x;
	int pos_y;
	int width;
	int height;
	int neighbor;
	int angle;
	void clear() { pos_x = pos_y = width = height = neighbor = angle = 0; }
	target_info() { clear(); }
};

//遍歷指定目錄下面的指定文件
vector<string> query_dir_file(string& target_dir,string& file_type)
{ 
	std::string path = target_dir;
	path += "\\*.";
	path += file_type;

	vector<string> result_file;
	struct _finddatai64_t file_info;
	intptr_t handle = _findfirsti64(path.c_str(), &file_info);
	if (handle != -1)
	{
		do
		{
			if (file_info.attrib & _A_SUBDIR) {}
			else result_file.push_back(file_info.name);
		} while (!_findnexti64(handle, &file_info));
	}

	return result_file;
}

//人臉檢測
bool face_mark(Mat& gray, unsigned char* buffer, target_info& info, int type)
{
	int* result = nullptr;
	switch (type)
	{
	case frontal:
		result = facedetect_frontal(buffer, (unsigned char*)(gray.ptr(0)),
			gray.cols, gray.rows, (int)gray.step, 1.2f, 2, 48, 0, 0);
		break;
	case frontal_surveillance:
		result = facedetect_frontal_surveillance(buffer, (unsigned char*)(gray.ptr(0)),
			gray.cols, gray.rows, (int)gray.step, 1.2f, 2, 48, 0, 0);
		break;
	case multiview:
		result = facedetect_multiview(buffer, (unsigned char*)(gray.ptr(0)),
			gray.cols, gray.rows, (int)gray.step,1.2f, 2, 48, 0, 0);
		break;
	case multiview_reinforce:
		result = facedetect_multiview_reinforce(buffer, (unsigned char*)(gray.ptr(0)),
			gray.cols, gray.rows, (int)gray.step, 1.2f, 3, 48, 0, 0);
		break;
	default: return false;
	}
	if (result && *result > 0)
	{
		short* temp = ((short*)(result + 1));
		info.pos_x = temp[0];
		info.pos_y = temp[1];
		info.width = temp[2];
		info.height = temp[3];
		info.neighbor = temp[4];
		info.angle = temp[5];
		return true;
	}
	return false;
}

//開始工作
void do_work()
{
	cout << "輸入圖片路徑:" << endl;
	string dir;
	getline(cin, dir);

	cout << "輸入圖片格式:" << endl;
	string file_type;
	getline(cin, file_type);

	cout << "是否繪製方框[yes / no]:" << endl;
	string draw_rect;
	bool is_draw = false;
	getline(cin, draw_rect);
	if (draw_rect == "yes")is_draw = true;

	vector<string> file_data = query_dir_file(dir, file_type);
	if (file_data.empty())
	{
		cout << "查找不到指定類型文件" << endl;
		return;
	}

	unsigned char* temp_buffer = new unsigned char[DETECT_BUFFER_SIZE];
	if (temp_buffer)
	{
		target_info current_info;
		fstream error_file(dir + "\\error.txt", fstream::out | fstream::binary);//保存沒有識別出來人臉的圖片
		for (int index = 0; index < file_data.size(); index++)
		{
			bool is_finish = false;
			string old_name = dir + "\\" + file_data[index];
			Mat target_buffer = imread(old_name);
			if (target_buffer.empty())continue;
			Mat target_gray;
			cvtColor(target_buffer, target_gray, cv::COLOR_RGB2GRAY);
			current_info.clear();
			for (int type = 0; type < operator_type::number; type++)
			{
				if (face_mark(target_gray, temp_buffer, current_info, type))
				{
					char new_name[1024]{ 0 };
					sprintf_s(new_name, "%s\\%d_%d_%d_%d_%d_%d_%d.%s", dir.c_str(),
						index, current_info.pos_x, current_info.pos_y,
						current_info.width, current_info.height,
						current_info.neighbor, current_info.angle, file_type.c_str());
					if (rename(old_name.c_str(), new_name) != -1)
						cout << "finish -> " << old_name << " to " << new_name << endl;
					if (is_draw)
					{
						rectangle(target_buffer,
							Rect(current_info.pos_x, current_info.pos_y,
								current_info.width, current_info.height),
							Scalar(0, 255, 0), 1);
						imwrite(new_name, target_buffer);
					}
					is_finish = true;
					break;
				}
			}
			if (is_finish == false)
			{
				if(error_file.is_open()) error_file << old_name << endl;
				cout << "error -> " << old_name << endl;
			}
		}
	}
	delete[] temp_buffer;
}

int main(int argc,char* argv[])
{
	do_work();
	cout << "工作完成...." << endl;
	cin.get();
	return 0;
}

如圖所示:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章