提交 b4b63cd6 编写于 作者: M marina.kolpakova

add softcascade to people detector sample

上级 e4f55a7e
......@@ -4,7 +4,7 @@
# ----------------------------------------------------------------------------
SET(OPENCV_CPP_SAMPLES_REQUIRED_DEPS opencv_core opencv_flann opencv_imgproc
opencv_highgui opencv_ml opencv_video opencv_objdetect opencv_photo opencv_nonfree
opencv_highgui opencv_ml opencv_video opencv_objdetect opencv_photo opencv_nonfree opencv_softcascade
opencv_features2d opencv_calib3d opencv_legacy opencv_contrib opencv_stitching opencv_videostab)
ocv_check_dependencies(${OPENCV_CPP_SAMPLES_REQUIRED_DEPS})
......
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <opencv2/softcascade/softcascade.hpp>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
using namespace cv;
using namespace std;
// static void help()
// {
// printf(
// "\nDemonstrate the use of the HoG descriptor using\n"
// " HOGDescriptor::hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());\n"
// "Usage:\n"
// "./peopledetect (<image_filename> | <image_list>.txt)\n\n");
// }
void filter_rects(const std::vector<cv::Rect>& candidates, std::vector<cv::Rect>& objects);
int main(int argc, char** argv)
{
Mat img;
FILE* f = 0;
char _filename[1024];
const std::string keys =
"{help h usage ? | | print this message and exit }"
"{cascade c | | path to cascade xml, if empty HOG detector will be executed }"
"{frame f | | wildchart pattern to frame source}"
"{min_scale |0.4 | minimum scale to detect }"
"{max_scale |5.0 | maxamum scale to detect }"
"{total_scales |55 | prefered number of scales between min and max }"
"{write_file wf |0 | write to .txt. Disabled by default.}"
"{write_image wi |0 | write to image. Disabled by default.}"
"{show_image si |1 | show image. Enabled by default.}"
"{threshold thr |-1 | detection threshold. Detections with score less then threshold will be ignored.}"
;
cv::CommandLineParser parser(argc, argv, keys);
parser.about("Soft cascade training application.");
if( argc == 1 )
if (parser.has("help"))
{
printf("Usage: peopledetect (<image_filename> | <image_list>.txt)\n");
parser.printMessage();
return 0;
}
img = imread(argv[1]);
if( img.data )
if (!parser.check())
{
parser.printErrors();
return 1;
}
int wf = parser.get<int>("write_file");
if (wf) std::cout << "resulte will be stored to .txt file with the same name as image." << std::endl;
int wi = parser.get<int>("write_image");
if (wi) std::cout << "resulte will be stored to image with the same name as input plus dt." << std::endl;
int si = parser.get<int>("show_image");
float minScale = parser.get<float>("min_scale");
float maxScale = parser.get<float>("max_scale");
int scales = parser.get<int>("total_scales");
int thr = parser.get<int>("threshold");
cv::HOGDescriptor hog;
cv::softcascade::Detector cascade;
bool useHOG = false;
std::string cascadePath = parser.get<std::string>("cascade");
if (cascadePath.empty())
{
strcpy(_filename, argv[1]);
useHOG = true;
hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
std::cout << "going to use HOG detector." << std::endl;
}
else
{
f = fopen(argv[1], "rt");
if(!f)
cv::FileStorage fs(cascadePath, cv::FileStorage::READ);
if( !fs.isOpened())
{
fprintf( stderr, "ERROR: the specified file could not be loaded\n");
return -1;
std::cout << "Soft Cascade file " << cascadePath << " can't be opened." << std::endl << std::flush;
return 1;
}
cascade = cv::softcascade::Detector(minScale, maxScale, scales, cv::softcascade::Detector::DOLLAR);
if (!cascade.load(fs.getFirstTopLevelNode()))
{
std::cout << "Soft Cascade can't be parsed." << std::endl << std::flush;
return 1;
}
}
HOGDescriptor hog;
hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
namedWindow("people detector", 1);
std::string src = parser.get<std::string>("frame");
std::vector<std::string> frames;
cv::glob(parser.get<std::string>("frame"), frames);
std::cout << "collected " << src << " " << frames.size() << " frames." << std::endl;
for(;;)
for (int i = 0; i < (int)frames.size(); ++i)
{
char* filename = _filename;
if(f)
std::string& frame_sourse = frames[i];
cv::Mat frame = cv::imread(frame_sourse);
if(frame.empty())
{
if(!fgets(filename, (int)sizeof(_filename)-2, f))
break;
//while(*filename && isspace(*filename))
// ++filename;
if(filename[0] == '#')
continue;
int l = (int)strlen(filename);
while(l > 0 && isspace(filename[l-1]))
--l;
filename[l] = '\0';
img = imread(filename);
}
printf("%s:\n", filename);
if(!img.data)
std::cout << "Frame source " << frame_sourse << " can't be opened." << std::endl << std::flush;
continue;
}
std::ofstream myfile;
if (wf)
myfile.open((frame_sourse.replace(frame_sourse.end() - 3, frame_sourse.end(), "txt")).c_str(), std::ios::out);
////
if (useHOG)
{
std::vector<cv::Rect> found, found_filtered;
// run the detector with default parameters. to get a higher hit-rate
// (and more false alarms, respectively), decrease the hitThreshold and
// groupThreshold (set groupThreshold to 0 to turn off the grouping completely).
hog.detectMultiScale(frame, found, 0, cv::Size(8,8), cv::Size(32,32), 1.05, 2);
filter_rects(found, found_filtered);
std::cout << "collected: " << (int)found_filtered.size() << " detections." << std::endl;
for (size_t ff = 0; ff < found_filtered.size(); ++ff)
{
cv::Rect r = found_filtered[ff];
cv::rectangle(frame, r.tl(), r.br(), cv::Scalar(0,255,0), 3);
fflush(stdout);
vector<Rect> found, found_filtered;
double t = (double)getTickCount();
// run the detector with default parameters. to get a higher hit-rate
// (and more false alarms, respectively), decrease the hitThreshold and
// groupThreshold (set groupThreshold to 0 to turn off the grouping completely).
hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2);
t = (double)getTickCount() - t;
printf("tdetection time = %gms\n", t*1000./cv::getTickFrequency());
size_t i, j;
for( i = 0; i < found.size(); i++ )
if (wf) myfile << r.x << "," << r.y << "," << r.width << "," << r.height << "," << 0.f << "\n";
}
}
else
{
Rect r = found[i];
for( j = 0; j < found.size(); j++ )
if( j != i && (r & found[j]) == r)
break;
if( j == found.size() )
found_filtered.push_back(r);
std::vector<cv::softcascade::Detection> objects;
cascade.detect(frame, cv::noArray(), objects);
std::cout << "collected: " << (int)objects.size() << " detections." << std::endl;
for (int obj = 0; obj < (int)objects.size(); ++obj)
{
cv::softcascade::Detection d = objects[obj];
if(d.confidence > thr)
{
float b = d.confidence * 1.5f;
std::stringstream conf(std::stringstream::in | std::stringstream::out);
conf << d.confidence;
cv::rectangle(frame, cv::Rect(d.bb.x, d.bb.y, d.bb.width, d.bb.height), cv::Scalar(b, 0, 255 - b, 255), 2);
cv::putText(frame, conf.str() , cv::Point(d.bb.x + 10, d.bb.y - 5),1, 1.1, cv::Scalar(25, 133, 255, 0), 1, CV_AA);
if (wf)
myfile << d.bb.x << "," << d.bb.y << ","
<< d.bb.width << "," << d.bb.height << "," << d.confidence << "\n";
}
}
}
for( i = 0; i < found_filtered.size(); i++ )
if (wi) cv::imwrite(frame_sourse + ".dt.png", frame);
if (wf) myfile.close();
if (si)
{
Rect r = found_filtered[i];
// the HOG detector returns slightly larger rectangles than the real objects.
// so we slightly shrink the rectangles to get a nicer output.
r.x += cvRound(r.width*0.1);
r.width = cvRound(r.width*0.8);
r.y += cvRound(r.height*0.07);
r.height = cvRound(r.height*0.8);
rectangle(img, r.tl(), r.br(), cv::Scalar(0,255,0), 3);
cv::imshow("pedestrian detector", frame);
cv::waitKey(10);
}
imshow("people detector", img);
int c = waitKey(0) & 255;
if( c == 'q' || c == 'Q' || !f)
break;
}
if(f)
fclose(f);
if (si) cv::waitKey(0);
return 0;
}
void filter_rects(const std::vector<cv::Rect>& candidates, std::vector<cv::Rect>& objects)
{
size_t i, j;
for (i = 0; i < candidates.size(); ++i)
{
cv::Rect r = candidates[i];
for (j = 0; j < candidates.size(); ++j)
if (j != i && (r & candidates[j]) == r)
break;
if (j == candidates.size())
objects.push_back(r);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册