c++调用opencv人脸检测(windows环境)
c++调用opencv人脸检测,检测出视频流里的人脸通过http发送到后台服务器,代码如下
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2\opencv.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <iostream>
#include <string>
#include <thread>
#include <stdio.h>
#include "threadsafe_queue.h"
#include <Winsock2.h>
#include <Windows.h>
#include "curl/curl.h"
#include "opencv2/objdetect.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include <io.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/locking.h>
#include <share.h>
#include <fcntl.h>
#pragma comment(lib, "libcurl.lib")
#pragma comment(lib, "wldap32.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "winmm.lib")
using namespace std;
using namespace cv;
threadsafe_queue<Mat> imgList;
threadsafe_queue<string> cutList;
int jump = 20;
bool tryflip;
CascadeClassifier cascade, nestedCascade;
double scale;
//��ȡ��Ƶ��
DWORD WINAPI GETVIDEO(LPVOID lpParamter)
{
FILE *fp = fopen("./video.txt", "r");
if (!fp)
{
printf("��video.txtʧ�ܣ�\n");
return -1;
}
char address[200];
fscanf(fp, "%s", address);
fclose(fp);
VideoCapture capture;
capture.open(address);
if (!capture.isOpened())
{
cout << "colud not load vodeo...." << endl;
return 0;
}
int jumpNum = 0;
while (1)
{
Mat frame;
capture >> frame;
if (frame.empty())
{
waitKey(1);
continue;
}
jumpNum += 1;
if (jumpNum >= jump)
{
jumpNum = 0;
}
else
{
continue;
}
resize(frame, frame, Size(460, 320),1);
imgList.push(frame.clone());
waitKey(2);
}
}
//�����Ƶ��
DWORD WINAPI CHECKIMG(LPVOID lpParamter)
{
while (1)
{
Mat img = imgList.wait_and_pop().clone();
/* cvNamedWindow("img", CV_WINDOW_NORMAL);
cvNamedWindow("cut", CV_WINDOW_NORMAL);*/
double t = 0;
vector<Rect> faces, faces2;
const static Scalar colors[] =
{
Scalar(255, 0, 0),
Scalar(255, 128, 0),
Scalar(255, 255, 0),
Scalar(0, 255, 0),
Scalar(0, 128, 255),
Scalar(0, 255, 255),
Scalar(0, 0, 255),
Scalar(255, 0, 255)};
Mat gray, smallImg;
cvtColor(img, gray, COLOR_BGR2GRAY);
double fx = 1 / scale;
resize(gray, smallImg, Size(), fx, fx, INTER_LINEAR_EXACT);
equalizeHist(smallImg, smallImg);
t = (double)getTickCount();
cascade.detectMultiScale(smallImg, faces,
1.1, 2, 0
//|CASCADE_FIND_BIGGEST_OBJECT
//|CASCADE_DO_ROUGH_SEARCH
| CASCADE_SCALE_IMAGE,
Size(30, 30));
if (tryflip)
{
flip(smallImg, smallImg, 1);
cascade.detectMultiScale(smallImg, faces2,
1.1, 2, 0
//|CASCADE_FIND_BIGGEST_OBJECT
//|CASCADE_DO_ROUGH_SEARCH
| CASCADE_SCALE_IMAGE,
Size(30, 30));
for (vector<Rect>::const_iterator r = faces2.begin(); r != faces2.end(); ++r)
{
faces.push_back(Rect(smallImg.cols - r->x - r->width, r->y, r->width, r->height));
}
}
t = (double)getTickCount() - t;
//printf("detection time = %g ms\n", t * 1000 / getTickFrequency());
for (size_t i = 0; i < faces.size(); i++)
{
Rect r = faces[i];
//imshow("cut", img(r));
string names = "./imgs/" + to_string(getTickCount()) + ".jpg";
bool iswrite=imwrite(names, img(r).clone());
cutList.push(names);
//Mat smallImgROI;
//vector<Rect> nestedObjects;
//Point center;
//Scalar color = colors[i % 8];
//int radius;
//double aspect_ratio = (double)r.width / r.height;
//if (0.75 < aspect_ratio && aspect_ratio < 1.3)
//{
// center.x = cvRound((r.x + r.width * 0.5) * scale);
// center.y = cvRound((r.y + r.height * 0.5) * scale);
// radius = cvRound((r.width + r.height) * 0.25 * scale);
// circle(img, center, radius, color, 3, 8, 0);
//}
//else
// rectangle(img, Point(cvRound(r.x * scale), cvRound(r.y * scale)),
// Point(cvRound((r.x + r.width - 1) * scale), cvRound((r.y + r.height - 1) * scale)),
// color, 3, 8, 0);
}
//imshow("img", img);
waitKey(2);
}
}
int write_data(void* buffer, int size, int nmemb, void* userp) {
std::string* str = dynamic_cast<std::string*>((std::string*)userp);
str->append((char*)buffer, size * nmemb);
return nmemb;
}
bool IsFileUsed(const char* filePath)
{
bool ret = false;
int fh = _sopen(filePath, _O_RDWR, _SH_DENYRW,
_S_IREAD | _S_IWRITE);
if (-1 == fh)
ret = true;
else
_close(fh);
return ret;
}
//�������������͵�������
DWORD WINAPI SENDIMG(LPVOID lpParamter)
{
FILE* fp = fopen("./http.txt", "r");
if (!fp)
{
printf("��video.txtʧ�ܣ�\n");
return -1;
}
char address[200];
fscanf(fp, "%s", address);
fclose(fp);
while (1)
{
std::string body;
std::string response;
std::string path =cutList.wait_and_pop();
while (IsFileUsed((char*)path.c_str())) {
waitKey(5);
}
char paths[200];
int i;
for ( i = 0; i < path.length(); i++)
paths[i] = path[i];
paths[i] = '\0';
CURL* curl;
CURLcode ret;
curl = curl_easy_init();
struct curl_httppost* post = NULL;
struct curl_httppost* last = NULL;
if (curl)
{
//cout << paths << endl;
curl_easy_setopt(curl, CURLOPT_URL, address); //ָ��url
curl_formadd(&post, &last, CURLFORM_PTRNAME, "img", CURLFORM_FILE, paths, CURLFORM_FILENAME, "hello.jpg", CURLFORM_END);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);//不做服务器认证
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);//不做客户端认证
curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); //����post����
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); //����Ӧ
curl_easy_setopt(curl, CURLOPT_WRITEDATA, response); //����Ӧ���ݵĵ�ַ
ret = curl_easy_perform(curl); //ִ������
if (ret == 0) {
curl_easy_cleanup(curl);
}
else {
cout << ret << endl;
}
}
else {
cout << -1 << endl;
}
while (IsFileUsed((char*)path.c_str())) {
waitKey(5);
}
remove(paths);
waitKey(2);
}
}
int main(char argc, char *argv[])
{
cv::CommandLineParser parser(argc, argv,
"{help h||}"
"{cascade|data/haarcascades/haarcascade_frontalface_alt.xml|}"
"{nested-cascade|data/haarcascades/haarcascade_eye_tree_eyeglasses.xml|}"
"{scale|1|}{try-flip||}{@filename||}");
string cascadeName = parser.get<string>("cascade");
string nestedCascadeName = parser.get<string>("nested-cascade");
scale = parser.get<double>("scale");
if (scale < 1)
scale = 1;
tryflip = parser.has("try-flip");
if (!parser.check())
{
parser.printErrors();
return 0;
}
if (!nestedCascade.load(samples::findFileOrKeep(nestedCascadeName)))
cerr << "WARNING: Could not load classifier cascade for nested objects" << endl;
if (!cascade.load(samples::findFile(cascadeName)))
{
cerr << "ERROR: Could not load classifier cascade" << endl;
return -1;
}
HANDLE getThread = CreateThread(NULL, 0, GETVIDEO, NULL, 0, NULL);
HANDLE checkThread = CreateThread(NULL, 0, CHECKIMG, NULL, 0, NULL);
HANDLE sendThread = CreateThread(NULL, 0, SENDIMG, NULL, 0, NULL);
while (1)
{
Sleep(10000);
}
return 0;
}