Skip to content

Commit f5c7cb4

Browse files
committed
face detect
1 parent 3bb80f5 commit f5c7cb4

File tree

3 files changed

+400
-0
lines changed

3 files changed

+400
-0
lines changed

detect/face_detection.cpp

+393
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,393 @@
1+
/*
2+
* =====================================================================================
3+
*
4+
* Filename: face_detection.cpp
5+
*
6+
* Description:
7+
*
8+
* Version: 1.0
9+
*
10+
* Revision: none
11+
* Compiler: arm-xilinx-linux-gnueabi-g++
12+
*
13+
* Author: DLX
14+
* =====================================================================================
15+
*/
16+
17+
#include "opencv2/opencv.hpp"
18+
#include "opencv/cxcore.h"
19+
20+
#include "opencv2/imgproc/imgproc.hpp"
21+
#include "opencv2/highgui/highgui.hpp"
22+
23+
#include <vector>
24+
#include <opencv2/contrib/contrib.hpp>
25+
26+
#include <opencv2/core/core.hpp>
27+
//#include "opencv2/high"
28+
//#include "opencv/cv.h"
29+
//#include "opencv/highgui.h"
30+
31+
32+
#include <stdio.h>
33+
#include <stdlib.h>
34+
#include <string.h>
35+
#include <assert.h>
36+
#include <math.h>
37+
#include <float.h>
38+
#include <limits.h>
39+
#include <time.h>
40+
#include <ctype.h>
41+
#include <sys/stat.h>
42+
#include <iostream>
43+
#include <algorithm>
44+
#include <sys/socket.h>
45+
#include <netinet/in.h>
46+
#include <arpa/inet.h>
47+
using namespace cv;
48+
49+
using std::cout;
50+
using std::endl;
51+
52+
53+
static CvMemStorage* storage = cvCreateMemStorage();
54+
static CvHaarClassifierCascade* cascade = 0;
55+
56+
void detect_and_draw( IplImage* image ,IplImage* image_old,int minX,int minY);
57+
bool less_by_x(const cv::Point& lhs, const cv::Point& rhs)
58+
{
59+
return lhs.x < rhs.x;
60+
}
61+
62+
bool less_by_y(const cv::Point& lhs, const cv::Point& rhs)
63+
{
64+
return lhs.y < rhs.y;
65+
}
66+
67+
const char* cascade_name =
68+
"haarcascade_frontalface_alt.xml";
69+
/* "haarcascade_profileface.xml";*/
70+
//static int init_flag = 0;
71+
int sockfd, portno, n;
72+
struct sockaddr_in serv_addr;
73+
char buffer[1024] = "hello dlx----------\n";
74+
int face_main()
75+
{
76+
CvCapture* capture = 0;
77+
IplImage *image =0;
78+
IplImage *frame, *frame_copy = 0;
79+
80+
Mat image_bmp;
81+
IplImage tmp;
82+
IplImage tmp2;
83+
//dlx modify
84+
Mat image_bmp_back;
85+
IplImage tmp_back;
86+
IplImage *image_back =0;
87+
IplImage *image_dst =0;
88+
IplImage *image_dst_gray =0;
89+
IplImage *image_dst_gray_canny =0;
90+
IplImage *image_skin =0;
91+
// int optlen = strlen("--cascade=");
92+
93+
94+
//if(init_flag == 0)
95+
//{
96+
97+
//portno = atoi(argv[2]);
98+
portno = 9001;
99+
sockfd = socket(AF_INET, SOCK_STREAM, 0);
100+
if (sockfd < 0)
101+
printf("ERROR opening socket\n");
102+
103+
//bzero((char *) &serv_addr, sizeof(serv_addr));
104+
memset(&serv_addr, 0, sizeof(serv_addr));
105+
serv_addr.sin_family = AF_INET;
106+
serv_addr.sin_addr.s_addr = inet_addr("192.168.1.40");
107+
serv_addr.sin_port = htons(portno);
108+
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
109+
perror("ERROR connecting1\n");
110+
memset(buffer, 0, 1024);
111+
//init_flag = 1;
112+
//}
113+
114+
115+
cascade_name = "./haarcascade_frontalface_alt2.xml";
116+
//opencv装好后haarcascade_frontalface_alt2.xml的路径,
117+
//也可以把这个文件拷到你的工程文件夹下然后不用写路径名cascade_name= "haarcascade_frontalface_alt2.xml";
118+
cascade = (CvHaarClassifierCascade*) cvLoad(cascade_name,0,0,0);//Problem happens
119+
120+
if( !cascade )
121+
{
122+
fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
123+
fprintf( stderr,
124+
"Usage: facedetect --cascade=\"<cascade_path>\" [filename|camera_index]\n" );
125+
return -1;
126+
}
127+
128+
//capture a pictrue from camera
129+
//capture = cvCaptureFromCAM(-1);//CV_CAP_ANY );
130+
//if captured successfully, save the image as capture.jpg , detect and draw
131+
132+
//cvSetCaptureProperty (capture,CV_CAP_PROP_FRAME_WIDTH,320);
133+
//cvSetCaptureProperty (capture,CV_CAP_PROP_FRAME_HEIGHT,240);
134+
if( 0 )
135+
{
136+
for(;;)
137+
{
138+
if( !cvGrabFrame( capture ))
139+
break;
140+
frame = cvRetrieveFrame( capture );
141+
if( !frame )
142+
break;
143+
if( !frame_copy )
144+
// frame_copy = cvCreateImage( cvSize(frame->width,frame->height),IPL_DEPTH_8U, frame->nChannels );
145+
146+
frame_copy = cvCreateImage( cvSize(320,240),IPL_DEPTH_8U, frame->nChannels );
147+
//copy frame to frame_copy and ensure frame_copy is not upside down
148+
if( frame->origin == IPL_ORIGIN_TL )
149+
cvResize(frame,frame_copy,CV_INTER_LINEAR);
150+
//cvCopy( frame, frame_copy, 0 );
151+
else
152+
{
153+
cvResize(frame,frame_copy,CV_INTER_LINEAR);
154+
cvFlip( frame, frame_copy, 0 );
155+
}
156+
//save captured image
157+
const char* filename = (char*)"./capture.bmp";// local path
158+
cvSaveImage(filename,frame_copy);
159+
//detect and draw
160+
//detect_and_draw( frame_copy );
161+
162+
}
163+
164+
cvReleaseImage( &frame_copy );
165+
cvReleaseCapture( &capture );
166+
}
167+
168+
else
169+
{
170+
//const char* filename = (char*)"./lena.bmp";// local path
171+
//const char* filename = (char*)"./tmp.bmp";// local path
172+
const char* filename = "/temp.bmp";
173+
image_bmp = imread(filename,1);
174+
tmp = IplImage(image_bmp);
175+
image = &tmp;
176+
if(!image)
177+
{
178+
printf("load image fault!\n");
179+
}
180+
181+
Mat output_mask;
182+
Mat output_image;
183+
Mat mask;
184+
185+
Mat skinCrCbHist = Mat::zeros(Size(256, 256), CV_8UC1);
186+
ellipse(skinCrCbHist, Point(113, 155.6), Size(23.4, 15.2), 43.0, 0.0, 360.0, Scalar(255, 255, 255), -1);
187+
188+
Mat element = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1) );
189+
Mat ycrcb_image;
190+
output_mask = Mat::zeros(image_bmp.size(), CV_8UC1);
191+
cvtColor(image_bmp, ycrcb_image, CV_BGR2YCrCb); //首先转换成到YCrCb空间
192+
193+
for(int i = 0; i < image_bmp.rows; i++) //利用椭圆皮肤模型进行皮肤检测
194+
{
195+
uchar* p = (uchar*)output_mask.ptr<uchar>(i);
196+
Vec3b* ycrcb = (Vec3b*)ycrcb_image.ptr<Vec3b>(i);
197+
for(int j = 0; j < image_bmp.cols; j++)
198+
{
199+
if(skinCrCbHist.at<uchar>(ycrcb[j][1], ycrcb[j][2]) > 0)
200+
p[j] = 255;
201+
}
202+
}
203+
204+
morphologyEx(output_mask,output_mask,MORPH_CLOSE,element);
205+
206+
207+
vector< vector<Point> > contours; // 轮廓
208+
vector< vector<Point> > filterContours; // 筛选后的轮廓
209+
vector< Vec4i > hierarchy; // 轮廓的结构信息
210+
contours.clear();
211+
hierarchy.clear();
212+
filterContours.clear();
213+
214+
findContours(output_mask, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
215+
typedef std::vector<cv::Point>::const_iterator PointIt;
216+
int minX = 640;
217+
int maxX = 0;
218+
int minY = 480;
219+
int maxY = 0;
220+
// 去除伪轮廓
221+
for (size_t i = 0; i < contours.size(); i++)
222+
{
223+
if (fabs(contourArea(Mat(contours[i]))) > 3000/*&&fabs(arcLength(Mat(contours[i]),true))<2000*/) //判断手进入区域的阈值
224+
{
225+
filterContours.push_back(contours[i]); printf("++ %d\n",fabs(contourArea(Mat(contours[i]))));
226+
//dlx add ----get the max,min of x,y ;http://stackoverflow.com/questions/18438706/finding-min-and-max-of-a-point-vector
227+
//std::pair<PointIt, PointIt> mmx
228+
PointIt mmx = std::min_element(contours[i].begin(),
229+
contours[i].end(),
230+
less_by_x);
231+
printf("min x:%d \n",mmx->x);
232+
if(minX > mmx->x)
233+
{
234+
minX = mmx->x;
235+
}
236+
237+
mmx = std::max_element(contours[i].begin(),
238+
contours[i].end(),
239+
less_by_x);
240+
printf("max x:%d \n",mmx->x);
241+
if(maxX < mmx->x)
242+
{
243+
maxX = mmx->x;
244+
}
245+
246+
mmx = std::min_element(contours[i].begin(),
247+
contours[i].end(),
248+
less_by_y);
249+
printf("min y:%d \n",mmx->y);
250+
if(minY > mmx->y)
251+
{
252+
minY = mmx->y;
253+
}
254+
255+
mmx = std::max_element(contours[i].begin(),
256+
contours[i].end(),
257+
less_by_y);
258+
printf("min y:%d \n",mmx->y);
259+
if(maxY < mmx->y)
260+
{
261+
maxY = mmx->y;
262+
}
263+
264+
}
265+
266+
}
267+
268+
269+
printf("minX=%d minY=%d maxX=%d maxY=%d \n\n",minX,minY,maxX,maxY);
270+
271+
if(minX > maxX || minY > maxY)
272+
{
273+
minX = 0;minY = 0;
274+
maxX = 640 - 1;maxY = 480 -1;
275+
//return 0;
276+
277+
}
278+
279+
output_mask.setTo(0);
280+
drawContours(output_mask, filterContours, -1, Scalar(255,0,0), CV_FILLED); //8, hierarchy);
281+
282+
image_bmp.copyTo(output_image, output_mask);
283+
//cut the ROI part
284+
cvSetImageROI(image,cvRect(minX,minY,maxX-minX,maxY-minY));
285+
//tmp2 = IplImage(image);
286+
cvSaveImage("/saveROI.bmp",image);
287+
tmp2 = IplImage(output_image);
288+
cvSaveImage("/save_skin_tmp2.bmp",&tmp2);
289+
290+
291+
292+
//dlx mod 5.3
293+
//detect_and_draw( &tmp2,image);
294+
//cvReleaseImage( &image );
295+
IplImage* ROI_img = cvCreateImage(cvGetSize(image),image->depth,image->nChannels);
296+
cvCopy(image,ROI_img,NULL);
297+
cvResetImageROI(image);
298+
detect_and_draw( ROI_img,image,minX,minY);
299+
cvReleaseImage( &ROI_img );
300+
}
301+
302+
cvReleaseHaarClassifierCascade( &cascade );
303+
304+
return 0;
305+
}
306+
307+
void detect_and_draw( IplImage* img ,IplImage* img_old,int minX,int minY)
308+
{
309+
static CvScalar colors = CV_RGB( 255, 0, 0);
310+
printf("detect=++++++++++++++++++++++++++++++==\n");
311+
double scale = 1.3;
312+
IplImage* gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );
313+
IplImage* small_img = cvCreateImage( cvSize( cvRound (img->width/scale),cvRound (img->height/scale)),8, 1 );
314+
315+
316+
cvCvtColor( img, gray, CV_BGR2GRAY );
317+
//dlx-----
318+
//cvSaveImage("/save_gray.bmp",gray);
319+
double t = (double)cvGetTickCount();
320+
cvResize( gray, small_img, CV_INTER_LINEAR );
321+
t = (double)cvGetTickCount() - t;
322+
printf( "cvResize time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );
323+
t = (double)cvGetTickCount();
324+
cvEqualizeHist( small_img, small_img );
325+
326+
t = (double)cvGetTickCount() - t;
327+
printf( "cvEqualizeHist time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );
328+
printf("detect=++++++++++++++++++++++++++++++==0.1\n");
329+
cvClearMemStorage( storage );
330+
if( cascade )
331+
{
332+
int i;
333+
t = (double)cvGetTickCount();
334+
CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,1.2, 2, CV_HAAR_DO_CANNY_PRUNING,cvSize(30, 30) );
335+
t = (double)cvGetTickCount() - t;
336+
printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );
337+
338+
for( i = 0; i < (faces ? faces->total : 0); i++ )
339+
{
340+
CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
341+
CvPoint center;
342+
int radius;
343+
center.x = cvRound((r->x + r->width*0.5)*scale + minX);
344+
center.y = cvRound((r->y + r->height*0.5)*scale + minY);
345+
radius = cvRound((r->width + r->height)*0.25*scale);
346+
cvCircle( img_old, center, radius, colors, 3, 8, 0 );
347+
printf("heloo------------------------------------people\n");
348+
349+
// send the image to server
350+
Mat ROI_mat = Mat(img);
351+
Mat faceImg = ROI_mat(*r).clone();
352+
353+
portno = 9001;
354+
sockfd = socket(AF_INET, SOCK_STREAM, 0);
355+
if (sockfd < 0)
356+
printf("ERROR opening socket\n");
357+
358+
//bzero((char *) &serv_addr, sizeof(serv_addr));
359+
memset(&serv_addr, 0, sizeof(serv_addr));
360+
serv_addr.sin_family = AF_INET;
361+
serv_addr.sin_addr.s_addr = inet_addr("192.168.1.40");
362+
serv_addr.sin_port = htons(portno);
363+
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
364+
perror("ERROR connecting1\n");
365+
memset(buffer, 0, 1024);
366+
367+
sprintf(buffer,"rows=%d , cols=%d , image.total()=%d \n",faceImg.rows,faceImg.cols,faceImg.total());
368+
faceImg = (faceImg.reshape(0,1));
369+
printf("rows =%d , cols = %d ,image.total() = %d \n",faceImg.rows,faceImg.cols,faceImg.total());
370+
printf("sockfd = %d \n",sockfd);
371+
n = send(sockfd,buffer,strlen(buffer),0);
372+
printf("send n =%d\n",n);
373+
if (n < 0)
374+
perror("ERROR writing to socket");
375+
376+
n = send(sockfd,faceImg.data,faceImg.total()*faceImg.elemSize(),0);
377+
if (n < 0)
378+
perror("ERROR writing to socket");
379+
printf("send n =%d\n",n);
380+
381+
close(sockfd);
382+
383+
}
384+
printf("detect=++++++++++++++++++++++++++++++1\n");
385+
}
386+
printf("==============================================\n");
387+
//const char* filename = (char*)"./detection.bmp";
388+
cvSaveImage("/tmp_detection.bmp",img_old);//save the result as "detection.bmp"
389+
cvReleaseImage( &gray );
390+
cvReleaseImage( &small_img );
391+
392+
393+
}

detect/libface_detection.so

105 KB
Binary file not shown.

0 commit comments

Comments
 (0)