运行opencv peopledetect2.4.10自带的facedetect.cpp出现问题,求解答

opencv 2.4.6 示例 facedetect - 推酷
opencv 2.4.6 示例 facedetect
昨天尝试运行opencv 2.4.6 的示例,结果出现了很多错误。
比如:ERROR: Could not load classifier cascade 我把haarcascade_frontalface_alt.xml以及haarcascade_eye_tree_eyeglasses.xml的路径都写对了,还是出现这个问题。最后发现是自己opencv配置有问题,我在visual studio里面配置的是release版本的DLL,但是我的程序编译的debug版本的,所以出错。将程序以release版本编译就不报这个错误。
另外,运行的过程中,窗口是灰色的,只显示一幅静态的灰色图像。cvQueryFrame返回NULL ,网上查了好久也没有解决,
原来有的时候cvQueryFrame获取的第一帧是空的,继续获取一次就对了:
IplImage *pSaveImg = cvQueryFrame(pCapturedImage); pSaveImg = cvQueryFrame(pCapturedImage);
下面是我修改过的facedetect.cpp
#include &opencv2/objdetect/objdetect.hpp&
#include &opencv2/highgui/highgui.hpp&
#include &opencv2/imgproc/imgproc.hpp&
#include &cctype&
#include &iostream&
#include &iterator&
#include &stdio.h&
static void help()
cout && &\nThis program demonstrates the cascade recognizer. Now you can use Haar or LBP features.\n&
&This classifier can recognize many kinds of rigid objects, once the appropriate classifier is trained.\n&
&It's most known use is for faces.\n&
&Usage:\n&
&./facedetect [--cascade=&cascade_path& this is the primary trained classifier such as frontal face]\n&
& [--nested-cascade[=nested_cascade_path this an optional secondary classifier such as eyes]]\n&
& [--scale=&image scale greater or equal to 1, try 1.3 for example&]\n&
& [--try-flip]\n&
& [filename|camera_index]\n\n&
&see facedetect.cmd for one call:\n&
&./facedetect --cascade=\&../../data/haarcascades/haarcascade_frontalface_alt.xml\& --nested-cascade=\&../../data/haarcascades/haarcascade_eye.xml\& --scale=1.3\n\n&
&During execution:\n\tHit any key to quit.\n&
&\tUsing OpenCV version & && CV_VERSION && &\n& &&
void detectAndDraw( Mat& img, CascadeClassifier& cascade,
CascadeClassifier& nestedCascade,
double scale, bool tryflip );
string cascadeName = &haarcascade_frontalface_alt.xml&;
string nestedCascadeName = &haarcascade_eye_tree_eyeglasses.xml&;
int main( int argc, const char** argv )
CvCapture* capture = 0;
Mat frame, frameCopy,
const string scaleOpt = &--scale=&;
size_t scaleOptLen = scaleOpt.length();
const string cascadeOpt = &--cascade=&;
size_t cascadeOptLen = cascadeOpt.length();
const string nestedCascadeOpt = &--nested-cascade&;
size_t nestedCascadeOptLen = nestedCascadeOpt.length();
const string tryFlipOpt = &--try-flip&;
size_t tryFlipOptLen = tryFlipOpt.length();
string inputN
bool tryflip =
CascadeClassifier cascade, nestedC
double scale = 1;
for( int i = 1; i & i++ )
cout && &Processing & && i && & & && argv[i] &&
if( pare( 0, cascadeOptLen, argv[i], cascadeOptLen ) == 0 )
cascadeName.assign( argv[i] + cascadeOptLen );
cout && & from which we have cascadeName= & && cascadeName &&
else if( pare( 0, nestedCascadeOptLen, argv[i], nestedCascadeOptLen ) == 0 )
if( argv[i][nestedCascadeOpt.length()] == '=' )
nestedCascadeName.assign( argv[i] + nestedCascadeOpt.length() + 1 );
if( !nestedCascade.load( nestedCascadeName ) )
cerr && &WARNING: Could not load classifier cascade for nested objects& &&
else if( pare( 0, scaleOptLen, argv[i], scaleOptLen ) == 0 )
if( !sscanf( argv[i] + scaleOpt.length(), &%lf&, &scale ) || scale & 1 )
scale = 1;
cout && & from which we read scale = & && scale &&
else if( pare( 0, tryFlipOptLen, argv[i], tryFlipOptLen ) == 0 )
cout && & will try to flip image horizontally to detect assymetric objects\n&;
else if( argv[i][0] == '-' )
cerr && &WARNING: Unknown option %s& && argv[i] &&
inputName.assign( argv[i] );
if( !cascade.load( cascadeName ) )
cerr && &ERROR: Could not load classifier cascade& &&
return -1;
if( inputName.empty() || (isdigit(inputName.c_str()[0]) && inputName.c_str()[1] == '\0') )
//capture = cvCaptureFromCAM( inputName.empty() ? 0 : inputName.c_str()[0] - '0' );
capture = cvCaptureFromCAM( CV_CAP_ANY );
int c = inputName.empty() ? 0 : inputName.c_str()[0] - '0' ;
if(!capture) cout && &Capture from CAM & && c && & didn't work& &&
else if( inputName.size() )
image = imread( inputName, 1 );
if( image.empty() )
capture = cvCaptureFromAVI( inputName.c_str() );
if(!capture) cout && &Capture from AVI didn't work& &&
image = imread( &lena.jpg&, 1 );
if(image.empty()) cout && &Couldn't read lena.jpg& &&
cvNamedWindow( &result&, 1 );
if( capture )
cout && &In capture ...& &&
//opencv 2.4.6 今天运行这个demo获取到的帧为空,网上搜索/questions/851679/saving-an-image-in-opencv 解释cvQueryFrame函数第一帧可能为空,要忽略
IplImage* iplImg = cvQueryFrame( capture );
iplImg=cvQueryFrame(capture);
frame = iplI
if( frame.empty() )
cout&&&frame empty!&&&
if( iplImg-&origin == IPL_ORIGIN_TL )
frame.copyTo( frameCopy );
flip( frame, frameCopy, 0 );
detectAndDraw( frameCopy, cascade, nestedCascade, scale, tryflip );
if( waitKey( 10 ) &= 0 )
goto _cleanup_;
waitKey(0);
_cleanup_:
cvReleaseCapture( &capture );
cout && &In image read& &&
if( !image.empty() )
detectAndDraw( image, cascade, nestedCascade, scale, tryflip );
waitKey(0);
else if( !inputName.empty() )
/* assume it is a text file containing the
list of the image filenames to be processed - one per line */
FILE* f = fopen( inputName.c_str(), &rt& );
char buf[1000+1];
while( fgets( buf, 1000, f ) )
int len = (int)strlen(buf),
while( len & 0 && isspace(buf[len-1]) )
buf[len] = '\0';
cout && &file & && buf &&
image = imread( buf, 1 );
if( !image.empty() )
detectAndDraw( image, cascade, nestedCascade, scale, tryflip );
c = waitKey(0);
if( c == 27 || c == 'q' || c == 'Q' )
cerr && &Aw snap, couldn't read image & && buf &&
fclose(f);
cvDestroyWindow(&result&);
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)} ;
Mat gray, smallImg( cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1 );
cvtColor( img, gray, CV_BGR2GRAY );
resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR );
equalizeHist( smallImg, smallImg );
t = (double)cvGetTickCount();
cascade.detectMultiScale( smallImg, faces,
//|CV_HAAR_FIND_BIGGEST_OBJECT
//|CV_HAAR_DO_ROUGH_SEARCH
|CV_HAAR_SCALE_IMAGE
Size(30, 30) );
if( tryflip )
flip(smallImg, smallImg, 1);
cascade.detectMultiScale( smallImg, faces2,
//|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() -
printf( &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& nestedO
Scalar color = colors[i%8];
double aspect_ratio = (double)r-&width/r-&
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 );
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() )
smallImgROI = smallImg(*r);
nestedCascade.detectMultiScale( smallImgROI, nestedObjects,
//|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 );
cv::imshow( &result&, img );
已发表评论数()
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
没有分页内容
图片无法显示
视频无法显示
与原文不一致PS:请参考最新的《》,绝对给力!由于Opencv版本升级,大多人开始用新版本VS,等等,这篇已经过时了,而且当时没有在文中加入更合适的简介的配置方法,所以有一些东西不再适用。重写一篇,,无论是Win7还是Win8,无论是VS2010, VS2012, 还是VS2013,无论是Opencv 2.x.x,方法都是一样的,只是配置思路和操作流程不同而已。
如果想重新编译Opencv,可以参考《》,不过新版本也许不用配置ttb了吧,没试过。
摘要:在VS2010环境中应用Opencv,网上找到了很多配置方法,但大多都是老版本的,很多新手面对最新版本的Opencv无从下手,就给新手童鞋写了这么一篇超级详细的配置攻略,贴上来共享。要强调一点的就是,这种配置方法里使用的Opencv库是直接安装Opencv时候自带的dll库,在你的VS里面是无法调试Opencv的。如果需要调试Opencv,必须应用自己编译出来的Opencv库,具体怎么编译自己的Opencv库,网上有很多例子,再此不再赘述。
1、下载软件
  下载OpenCV-2.4.0,双击解压到%opencv%(凡是出现%opencv%的地方均替换为你自己opencv的路径全名,如D:\program\opencv)。
  下载VS2010,安装。
&2、配置OpenCV环境变量
  计算机-&(右键)属性-&高级系统设置-&高级(标签)-&环境变量-&(双击)path(用户,系统里面的path任选其一)-&在变量值里面添加& %opencv%\build\x86\vc10\bin&和&%opencv%\build\common\tbb\ia32\vc10&(里面的%opencv%记得换成自己的opencv路径。例如我的:D:\program\ifly\D:\Program Files (x86)\opencv\build\x86\vc10\D:\Program Files (x86)\opencv\build\common\tbb\ia32\vc10)。
3、配置工程的opencv依赖(每次新建工程都要重新配置,要执行此步骤请先跳到第4步建立工程)
1)、项目(菜单项)-&&属性-&VC++目录:需要配置&包含目录&和&库目录&两项。
2)、配置&包含目录&项:添加行&%opencv%\build\include&即可。
但在运行别人的opencv项目时,可能别人直接引用了上述目录的子目录路径,如果出现include错误,则再添加&%opencv%\build\include\opencv&和(或)&%opencv%\build\include\opencv2&,即可解决问题。
3)、配置&库目录&项:添加行&%opencv%\build\x86\vc10\lib&即可。
4)、配置连接器:项目(菜单项)-&&属性-&连接器-&输入-&附加依赖项
针对debug配置添加以下库:
opencv_calib3d240d.lib
opencv_contrib240d.lib
opencv_core240d.lib
opencv_features2d240d.lib
opencv_flann240d.lib
opencv_gpu240d.lib
opencv_highgui240d.lib
opencv_imgproc240d.lib
opencv_legacy240d.lib
opencv_ml240d.lib
opencv_objdetect240d.lib
opencv_ts240d.lib
opencv_video240d.lib
如果是release配置(以后再说,只需要添加上面的debug配置就行了现在),则添加:
opencv_calib3d240.lib
opencv_contrib240.lib
opencv_core240.lib
opencv_features2d240.lib
opencv_flann240.lib
opencv_gpu240.lib
opencv_highgui240.lib
opencv_imgproc240.lib
opencv_legacy240.lib
opencv_ml240.lib
opencv_objdetect240.lib
opencv_ts240.lib
opencv_video240.lib
4、用VS2010新建控制台工程测试:
1)、文件-&新建-&项目-&Visual C++-&Win32 控制台应用程序(输入名称test)
2)、确定-&下一步-&附加选项选&空项目&-&完成
3)、解决方案资源管理器-&源文件(右键)-&添加-&新建项
4)、Visual C++-&C++文件:输入名称test点添加
5)、粘贴下面的代码,保存
1 #include &opencv2\opencv.hpp&
2 #include &iostream&
3 #include &string&
4 using namespace
5 using namespace
6 int main()
Mat img = imread("pp.jpg");
if(img.empty())
cout&&"error";
return -1;
imshow("xx的靓照",img);
waitKey();
6)、把自己的靓照改名为pp.jpg,然后放到工程项目的test文件夹里面(是里面那个test文件夹)
7)、按照第3步骤的方法配置工程的opencv依赖。
8)、按F5,如果你的图片出来了就OK了。
阅读(...) 评论()如何从0学习opencv,完成类似人脸检测的毕设?
本人毕业设计选择了 基于OpenCV的图像人脸分割系统研究与实现 这个题目。要求大概是:利用OpenCV库通过颜色特征比对、人脸关键点特征提取等方法对复杂背景下人脸区域进行识别,并确定人脸轮廓的系统。
以前没没接触过opencv,学校没有opencv的课程。现在刚把vs2015+opencv3环境配置好。有以下问题请求帮助1.新手入门,用什么版本的opencv和vs好些?2.需要先复习c++,然后看一本图像处理基础 一类的书吗?还是直接找opencv的书看?没学过计算机图像一类的课程。各位推荐下学习的书目顺序。3.我打算现在就开始弄毕设,各位分析下进度赶得上不?需要如何安排下?4.这方面有没有视频教程?目前就想到这些问题,希望各位师兄们的帮助~
按时间排序
人脸识别,就先别接触opencv的人脸库了,太容易调用了,半个小时就能搞个所谓的人脸识别,想要做产品,还是先从基础来,多去研究祖传的几种人脸识别算法。
为什么我大一也要做人脸识别。直接懵逼
一般基于opencv自带的例子,好好研究一下,再根据实际应用情况修改就可以了。最近做的一个瞳孔跟踪检测的demo:
把学习opencv的前几章看看,然后再找专门的人脸识别算法实现
之前本人做过一个识别身份证号码的,我用的是Python,好像是opencv2吧(记不清了)。最后实现了,代码才不到一百行,调几个opencv的函数就可以了。但我建议用c++版本的,这个版本的网上资源多,可以去参考。IDE而言好像都差不多吧,尽量避免用VS,太占资源了。想赶进度,需要有c++基础,不然很难,毕竟opencv只是一个函数库
现成人脸检测代码,直接以用:环境当然是Ubuntu + Cpp 最佳,一键安装OpenCV脚本:Python,Java, Cpp分别在Windows, Mac 和Ubuntu下都测过,个人感受可用性最高的是Ubuntu+Cpp
Opencv本身已经有训练跟预测的函数了,人脸检测也有。所以你要做的只是call而已。当然,基本的什么二值化,归一化,Mat,IplImage等数据结构的转换搞懂,差不多可以做了。我也就大二……基本是做完了
从0开始?必须从理论开始啊,我看的是数字图像处理,那本绿绿的厚厚的书。没有理论你连opencv的api都看不懂。opencv支持其他语言,我当初用的是Java,c++的api文档最好,java的很一般。我课程作业做的是类似谷歌的图片搜索那种,用了两周。代码都自己写,opencv只是被我拿来将jpg转成矩阵而已,算法都自己写。我课程也只是学基础,做图片搜索只是感兴趣然后自己上知网搜论文看论文,看了一个星期论文吧。你也可以去抄代码,网上很多的,但是毕设检查肯定会问你理论,所以基础和实现原理必须了解。理论基础起码两三个星期吧,一个星期论文两个星期代码,一个多月应该可以。
如何21天学会c++
openCV只是一个库,就是一堆现成的函数,只管调用就可以,关键是先把C++学好
建议你去看看毛星宇的《opencv3编程入门》,讲解的通俗易懂,而且里面还有大量的样例程序和它的部分注释。我看了这本书以后,感觉对opencv有一个整体上的认识,很适合初学者,而且该可以当做opencv使用手册,特别方便。还涉及到opencv里面一些函数处理图像的算法分析,谅解推荐。对了,里面还有关于安装opencv库的详细步骤。
实现直接调函数就好了,论文上把用的函数算法讲清楚
用python去做opencv
我读研期间做图像这块的 有很快用opencv 的工具做一个停车场车位检测和车牌识别
仅仅是一些内置工具的使用 就可以完成 另外推荐python是因为opencv 在python的借口也很强大
而且上手比较容易
看两小时官方文档即可
调用API简单得shi,如果自己完全实现还挺有意思。调用人家OpenCV写好的API,永远不知道什么是人脸识别。import cv2
import numpy
face_cascade = cv2.CascadeClassifier("/home/jasonleaster/opencv-3.0.0/data/haarcascades/haarcascade_frontalface_default.xml")
#image = cv2.imread("/home/jasonleaster/IMG_743.jpg")
image = cv2.imread("/home/jasonleaster/positive8.jpg")
dst = cv2.resize(image, (300, 300), interpolation = cv2.INTER_CUBIC)
gray = cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.2, 5)
for (x, y, w, h) in faces:
cv2.rectangle(dst, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imshow('YCM', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
问题来了,你会发现,这里调用了一个"神秘文件" xml结尾的。这里面是一堆数据。如果题主阅读过相关论文,不难猜到这里是cascade 针对正人脸的训练好的模型数据。用了一个API detectMultiScale,接着后面的for循环就开始画绿色的框框了。毕设的深度就在于,你能追究到这个API的实现到什么程度,能不能自己写一个?(目测没有学校教OpenCV,难道我们学习的东东都要学校教才会么?大大的疑问)(题主,加油)
如果是本科毕设,真不用这么麻烦。如果有C++基础最好,没有也无所谓,有点编程基础就行,openCV很多封装好的库函数,直接调用就行了。找点关于openCV的书,看看函数都是怎么调用的就行了。视频个人感觉没有必要。不懂的地方,建议可以去看看别人的技术博客或者论坛~应付本科毕设,足够了~
本人也是毕设现学opencv,只有可怜的C基础,导师给我表情识别的题目。当时就懵逼了,感觉根本做不出来。后来就从C复习起,看了《学习opencv》和各种博客论文,现在已经基本实现预期功能,就差界面搭建了。用心去做,比你想的简单。对了,想完成毕设参考硕博论文是不错的主意,他们思路清晰,很简单。对于某一点理论不懂就搜论文就可以了。
邪派速成学习法(1周内搞定毕设):git clone /Itseez/opencv
cd opencv/samples/cpp
按如下次序研究几个范例源文件:1.
#怎么用Cascade特征识别2.
#脸-&五官如果设计到追踪和多目标识别,继续往下3.
#图像处理、keypoint4.
#稳定滤波、路径预测扩展阅读5. 6. PS: 记得一边看范例一遍查阅API Reference,慢慢往外延伸,尽早尝试动手写自己的程序和试错。
我也是研究了opencv,要做毕业设计。正好研究到了人脸识别。人脸识别是有一个例子程序的。研究发现它识别时要用到一个xml的文件。而且还有可以识别眼睛的。搜索发现。xml里面的是特征码。识别算法就是通过这些特征值来识别的。也就是说理论上只要改变xml里面的值是可以用这个算法识别所有物体的,不仅仅是人脸。所以问题就变成了怎么得到算法能识别的,我们控制的xml。我搜索到了。得到opencv的源码后,用cmake生成一个vs的解决方案,打开后在app的文件夹里有三个项目,其中一个就是用来生成xml的,专业的说法是训练器训练机器,怎么训练自己搜吧,反正挺麻烦的。~我那会儿自己搞的时候没人教。花了差不多一个月才搞清楚整个流程。斗出来就这么几个字。
已有帐号?
无法登录?
社交帐号登录c++ - OpenCV 2.4.5 face detection - Code Review Stack Exchange
to customize your list.
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.
Here's how it works:
Anybody can ask a question
Anybody can answer
The best answers are voted up and rise to the top
This code is supposed to grab live camera feed, display feed in a window, mark in rectangles all detected faces, get the biggest detected face (by total area), display it in separate window, convert it to grayscale and finally save as PNG to hard disk, in project directory.
Any ideas for optimizing this code? It has to be OpenCV 2.4.5 compliant.
I kindly ask only people familiar with OpenCV2 to give their advice. They know what I mean as for lot of us there is sometimes problem adapting from OpenCV1 to OpenCV2.
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include &iostream&
#include &stdio.h&
// Function Headers
void detectAndDisplay(Mat frame);
// Global variables
// Copy this file from opencv/data/haarscascades to target folder
string face_cascade_name = "c:/haarcascade_frontalface_alt.xml";
CascadeClassifier face_
string window_name = "Capture - Face detection";
// Number of file to be saved
// Function main
int main(void)
VideoCapture capture(0);
if (!capture.isOpened())
// check if we succeeded
return -1;
// Load the cascade
if (!face_cascade.load(face_cascade_name))
printf("--(!)Error loading\n");
return (-1);
// Read the video stream
capture &&
// Apply the classifier to the frame
if (!frame.empty())
detectAndDisplay(frame);
printf(" --(!) No captured frame -- Break!");
int c = waitKey(10);
if (27 == char(c))
// Function detectAndDisplay
void detectAndDisplay(Mat frame)
std::vector&Rect&
Mat frame_
cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
equalizeHist(frame_gray, frame_gray);
// Detect faces
face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));
// Set Region of Interest
cv::Rect roi_b;
cv::Rect roi_c;
size_t ic = 0; // ic is index of current element
int ac = 0; // ac is area of current element
size_t ib = 0; // ib is index of biggest element
int ab = 0; // ab is area of biggest element
for (ic = 0; ic & faces.size(); ic++) // Iterate through all current elements (detected faces)
roi_c.x = faces[ic].x;
roi_c.y = faces[ic].y;
roi_c.width = (faces[ic].width);
roi_c.height = (faces[ic].height);
ac = roi_c.width * roi_c. // Get the area of current element (detected face)
roi_b.x = faces[ib].x;
roi_b.y = faces[ib].y;
roi_b.width = (faces[ib].width);
roi_b.height = (faces[ib].height);
ab = roi_b.width * roi_b. // Get the area of biggest element, at beginning it is same as "current" element
if (ac & ab)
roi_b.x = faces[ib].x;
roi_b.y = faces[ib].y;
roi_b.width = (faces[ib].width);
roi_b.height = (faces[ib].height);
crop = frame(roi_b);
resize(crop, res, Size(128, 128), 0, 0, INTER_LINEAR); // This will be needed later while saving images
cvtColor(crop, gray, CV_BGR2GRAY); // Convert cropped image to Grayscale
// Form a filename
filename = "";
ssfn && filenumber && ".png";
filename = ssfn.str();
filenumber++;
imwrite(filename, gray);
Point pt1(faces[ic].x, faces[ic].y); // Display detected faces on main window - live stream from camera
Point pt2((faces[ic].x + faces[ic].height), (faces[ic].y + faces[ic].width));
rectangle(frame, pt1, pt2, Scalar(0, 255, 0), 2, 8, 0);
// Show image
sstm && "Crop area size: " && roi_b.width && "x" && roi_b.height && " Filename: " &&
text = sstm.str();
putText(frame, text, cvPoint(30, 30), FONT_HERSHEY_COMPLEX_SMALL, 0.8, cvScalar(0, 0, 255), 1, CV_AA);
imshow("original", frame);
if (!crop.empty())
imshow("detected", crop);
destroyWindow("detected");
27.5k9102205
Your header asks for optimization, but your question asks for any ideas for improving the code. I'll answer the latter. If you need to optimize in terms of execution speed or memory use, I recommend using a profiler to measure what the critical path is.
Overall design
Your program uses a very C-like structure. Using an object-oriented approach can usually offer many benefits. For example, it will limit the scope of your global variables, since they can be member variables instead.
Your program uses both C++ and C-style IO. I strongly advice you to pick one of them. My recommendation is C++ iostreams, as they are type-safe.
Inconsistent style
Your programming
you do different things in different parts of the program. That looks very untidy. For example, at one point you do:
if (!capture.isOpened())
// check if we succeeded
return -1;
whereas later in the same function, another one-line if gets braces:
if (27 == char(c))
Personally, I prefer to write if statements like this:
if (!capture.isOpened()) return -1;
or over multiple lines and with braces. This avoids the risk of code like this:
if (!foo.bar())
printf(" --(!) No captured frame -- Break!");
foo.cleanup()
(In the previous snippet, foo.cleanup() is likely supposed to be run only if the if triggers, but will be run regardless.)
Another example is that at one point you do return -1;, but later you do return (-1);. P return is not a function.
Readability
Some of your variables have very poor names. Instead of this:
size_t ic = 0; // ic is index of current element
std::size_t index_current = 0;
Another thing that greatly boosts readability is avoiding literals in function calls. For example:
face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2,
0 | CASCADE_SCALE_IMAGE, Size(30, 30));
What's 1.1? 2? Why is the size 30x30? What do they mean? Are they correct? What possible values can they have? I think it's much better to define symbolic constants instead:
const float size_factor = 1.1;
const std::size_t num_buffers = 2;
const Size face_size(30, 30);
face_cascade.detectMultiScale(frame_gray, faces, size_factor, num_buffers, 0 | CASCADE_SCALE_IMAGE, face_size);
(The names I have given them are likely not what they actually mean. This is just an example.) An addition benefit with this is that code like this:
const float percentage = 20000f;
do_something(some_file, percentage);
Is more likely to be picked up as a possible error than this:
do_something(some_file, 20000f);
On the same note, 0 | CASCADE_SCALE_IMAGE is always exactly the same as CASCADE_SCALE_IMAGE, so you can skip the superfluous 0 |.
I think comments above the relevant line is more readable than comments beside the relevant line. In other words, prefer
// Get the area of biggest element, at beginning it is same as "current" element
ab = roi_b.width * roi_b.
ab = roi_b.width * roi_b. // Get the area of biggest element, at beginning it is same as "current" element
Also, some of your comments are unnecessary. Comments should explain why, rather than what or how. Comments should not repeat what the code is already saying. // Function main is a great example of a comment that does not add information. Another example is // check if we succeeded.
Personally, I think brief statements of what is going on are good, as long as it doesn't get too much. For example the // Detect faces comment -- I think that's OK.
Small smells and other details
Avoid polluting the global namespace with using directives.
In C++, int main(void) and int main() is exactly the same. Drop void -- this is not C.
I personally don't like , but that's just a matter of preference.
Limit the scope of variables as much as possible. For example, ic should be restricted to the for loop, as should filename.
Your program has very little error handling.
If C++11 is an option, consider using a range-based (foreach-style) for loop
Like this:
for (auto const& face : faces)
roi_c.x = face.x;
roi_c.y = face.y;
2,50011032
This is rather messy code, lots of inconsistencies and I doubt it really works.
It looks like something you have written and not bothered to review yourself.
Writing code is normally an iterative process (for me anyway), whereby you
write something and then consider whether it is any good.
Then you refine the
solution and consider again.
Your idea of what is "any good" will develop
over time, but inconsistency and repetition are clearly not good.
A few observations:
Embedded paths: It is best not to embed paths in your code.
For example
the include file paths should be defined during the build (with -I) and the
face_cascade_name variable should get its value some other way, eg through
arguments to main.
In this code, faces is a vector of Rect and roi_c is also a Rect.
roi_c.x = faces[ic].x;
roi_c.y = faces[ic].y;
roi_c.width = (faces[ic].width);
roi_c.height = (faces[ic].height);
ac = roi_c.width * roi_c. // area of current element
roi_b.x = faces[ib].x;
roi_b.y = faces[ib].y;
roi_b.width = (faces[ib].width);
roi_b.height = (faces[ib].height);
ab = roi_b.width * roi_b. // area of biggest element
if (ac & ab)
roi_b.x = faces[ib].x;
roi_b.y = faces[ib].y;
roi_b.width = (faces[ib].width);
roi_b.height = (faces[ib].height);
crop = frame(roi_b);
But roi_c is never used again and roi_b is assigned the same
value twice!
My guess is the second assignment should be of roi_c to roi_b,
but the whole would be better as:
int area_c = faces[ic].width * faces[ic].
int area_b = faces[ib].width * faces[ib].
if (area_c & area_b) {
roi = faces[ic];
roi = faces[ib];
crop = frame(roi);
Your coud also pass by reference to frame instead of passing by value.
And you might add an area method to the Rect class.
protected by ♦
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10
on this site.
Would you like to answer one of these
Not the answer you're looking for?
Browse other questions tagged
Code Review Stack Exchange works best with JavaScript enabled

我要回帖

更多关于 opencv detect函数 的文章

 

随机推荐