C++利用opencv实现人脸检测

2025-05-27 0 35

小编所有的帖子都是基于unbuntu系统的,当然稍作修改同样试用于windows的,经过小编的绞尽脑汁,把刚刚发的那篇python 实现人脸和眼睛的检测的程序用C++ 实现了,当然,也参考了不少大神的博客,下面我们就一起来看看:

Linux系统下安装opencv我就再啰嗦一次,防止有些人没有安装没调试出来喷小编的程序是个坑,
sudo apt-get install libcv-dev
sudo apt-get install libopencv-dev
看看你的usr/share/opencv/haarcascades目录下有没有出现几个训练集.XML文件,接下来我拿人脸和眼睛检测作为实例玩一下,程序如下:

好多人不会编译opencv,我再多写几句解决一下好多菜鸟的困难吧

copy完代码之后,保存为xiaorun.cpp哦,记得编译试用个g++ -o xiaorun ./xiaorun.cpp -lopencv_highgui -lopenc_imgproc -lopencv_core -lopencv_objdetect

即可实现

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154
#include <opencv2/highgui/highgui.hpp>

#include <opencv2/imgproc/imgproc.hpp>

#include <opencv2/core/core.hpp>

#include <opencv2/objdetect/objdetect.hpp>

#include <iostream>

using namespace cv;

using namespace std;

void detectAndDraw( Mat& img, CascadeClassifier& cascade,

CascadeClassifier& nestedCascade,

double scale, bool tryflip );

int main()

{

CascadeClassifier cascade, nestedCascade;

bool stop = false;

cascade.load("/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml");

nestedCascade.load("/usr/share/opencv/haarcascades/haarcascade_eye.xml");

// frame = imread("renlian.jpg");

VideoCapture cap(0); //打开默认摄像头

if(!cap.isOpened())

{

return -1;

}

Mat frame;

Mat edges;

while(!stop)

{

cap>>frame;

detectAndDraw( frame, cascade, nestedCascade,2,0 );

if(waitKey(30) >=0)

stop = true;

imshow("cam",frame);

}

//CascadeClassifier cascade, nestedCascade;

// bool stop = false;

//训练好的文件名称,放置在可执行文件同目录下

// cascade.load("/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml");

// nestedCascade.load("/usr/share/opencv/haarcascades/aarcascade_eye.xml");

// frame = imread("renlian.jpg");

// detectAndDraw( frame, cascade, nestedCascade,2,0 );

// waitKey();

//while(!stop)

//{

// cap>>frame;

// detectAndDraw( frame, cascade, nestedCascade,2,0 );

if(waitKey(30) >=0)

stop = true;

//}

return 0;

}

void detectAndDraw( Mat& img, CascadeClassifier& cascade,

CascadeClassifier& nestedCascade,

double scale, bool tryflip )

{

int i = 0;

double t = 0;

//建立用于存放人脸的向量容器

vector<Rect> faces, faces2;

//定义一些颜色,用来标示不同的人脸

const static Scalar colors[] = {

CV_RGB(0,0,255),

CV_RGB(0,128,255),

CV_RGB(0,255,255),

CV_RGB(0,255,0),

CV_RGB(255,128,0),

CV_RGB(255,255,0),

CV_RGB(255,0,0),

CV_RGB(255,0,255)} ;

//建立缩小的图片,加快检测速度

//nt cvRound (double value) 对一个double型的数进行四舍五入,并返回一个整型数!

Mat gray, smallImg( cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1 );

//转成灰度图像,Harr特征基于灰度图

cvtColor( img, gray, CV_BGR2GRAY );

// imshow("灰度",gray);

//改变图像大小,使用双线性差值

resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR );

// imshow("缩小尺寸",smallImg);

//变换后的图像进行直方图均值化处理

equalizeHist( smallImg, smallImg );

//imshow("直方图均值处理",smallImg);

//程序开始和结束插入此函数获取时间,经过计算求得算法执行时间

t = (double)cvGetTickCount();

//检测人脸

//detectMultiScale函数中smallImg表示的是要检测的输入图像为smallImg,faces表示检测到的人脸目标序列,1.1表示

//每次图像尺寸减小的比例为1.1,2表示每一个目标至少要被检测到3次才算是真的目标(因为周围的像素和不同的窗口大

//小都可以检测到人脸),CV_HAAR_SCALE_IMAGE表示不是缩放分类器来检测,而是缩放图像,Size(30, 30)为目标的

//最小最大尺寸

cascade.detectMultiScale( smallImg, faces,

1.1, 2, 0

//|CV_HAAR_FIND_BIGGEST_OBJECT

//|CV_HAAR_DO_ROUGH_SEARCH

|CV_HAAR_SCALE_IMAGE

,Size(30, 30));

//如果使能,翻转图像继续检测

if( tryflip )

{

flip(smallImg, smallImg, 1);

// imshow("反转图像",smallImg);

cascade.detectMultiScale( smallImg, faces2,

1.1, 2, 0

//|CV_HAAR_FIND_BIGGEST_OBJECT

//|CV_HAAR_DO_ROUGH_SEARCH

|CV_HAAR_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)cvGetTickCount() - t;

// qDebug( "detection time = %g ms\\n", t/((double)cvGetTickFrequency()*1000.) );

for( vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++ )

{

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, cvPoint(cvRound(r->x*scale), cvRound(r->y*scale)),

cvPoint(cvRound((r->x + r->width-1)*scale), cvRound((r->y + r->height-1)*scale)),

color, 3, 8, 0);

if( nestedCascade.empty() )

continue;

smallImgROI = smallImg(*r);

//同样方法检测人眼

nestedCascade.detectMultiScale( smallImgROI, nestedObjects,

1.1, 2, 0

//|CV_HAAR_FIND_BIGGEST_OBJECT

//|CV_HAAR_DO_ROUGH_SEARCH

//|CV_HAAR_DO_CANNY_PRUNING

|CV_HAAR_SCALE_IMAGE

,Size(30, 30) );

for( vector<Rect>::const_iterator nr = nestedObjects.begin(); nr != nestedObjects.end(); nr++ )

{

center.x = cvRound((r->x + nr->x + nr->width*0.5)*scale);

center.y = cvRound((r->y + nr->y + nr->height*0.5)*scale);

radius = cvRound((nr->width + nr->height)*0.25*scale);

circle( img, center, radius, color, 3, 8, 0 );

}

}

// imshow( "识别结果", img );

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持快网idc。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 C++利用opencv实现人脸检测 https://www.kuaiidc.com/73089.html

相关文章

发表评论
暂无评论