add ROI support
This commit is contained in:
parent
6a3a723938
commit
157ab66ab9
@ -556,9 +556,11 @@ public:
|
|||||||
// Param image is a frame on which detector will be applied.
|
// Param image is a frame on which detector will be applied.
|
||||||
// Param rois is a vector of regions of interest. Only the objects that fall into one of the regions will be returned.
|
// Param rois is a vector of regions of interest. Only the objects that fall into one of the regions will be returned.
|
||||||
// Param objects is an output array of Detections
|
// Param objects is an output array of Detections
|
||||||
virtual void detect(const Mat& image, const std::vector<cv::Rect>& rois, std::vector<Detection>& objects) const;
|
virtual void detect(InputArray image, InputArray rois, std::vector<Detection>& objects) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void detectNoRoi(const Mat& image, std::vector<Detection>& objects) const;
|
||||||
|
|
||||||
struct Filds;
|
struct Filds;
|
||||||
Filds* filds;
|
Filds* filds;
|
||||||
|
|
||||||
|
@ -81,13 +81,12 @@ PERF_TEST_P(detect, SCascade,
|
|||||||
ASSERT_TRUE(fs.isOpened());
|
ASSERT_TRUE(fs.isOpened());
|
||||||
ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode()));
|
ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode()));
|
||||||
|
|
||||||
std::vector<cv::Rect> rois;
|
|
||||||
std::vector<detection_t> objectBoxes;
|
std::vector<detection_t> objectBoxes;
|
||||||
cascade.detect(colored, rois, objectBoxes);
|
cascade.detect(colored, cv::noArray(), objectBoxes);
|
||||||
|
|
||||||
TEST_CYCLE()
|
TEST_CYCLE()
|
||||||
{
|
{
|
||||||
cascade.detect(colored, rois, objectBoxes);
|
cascade.detect(colored, cv::noArray(), objectBoxes);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Rect> rects;
|
vector<Rect> rects;
|
||||||
|
@ -510,16 +510,9 @@ bool cv::SCascade::load(const FileNode& fn)
|
|||||||
return filds->fill(fn, minScale, maxScale);
|
return filds->fill(fn, minScale, maxScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cv::SCascade::detect(const Mat& image, const std::vector<cv::Rect>& /*rois*/, std::vector<Detection>& objects) const
|
void cv::SCascade::detectNoRoi(const cv::Mat& image, std::vector<Detection>& objects) const
|
||||||
{
|
{
|
||||||
// only color images are supperted
|
|
||||||
CV_Assert(image.type() == CV_8UC3);
|
|
||||||
|
|
||||||
Filds& fld = *filds;
|
Filds& fld = *filds;
|
||||||
fld.calcLevels(image.size(), scales);
|
|
||||||
|
|
||||||
objects.clear();
|
|
||||||
|
|
||||||
// create integrals
|
// create integrals
|
||||||
ChannelStorage storage(image, fld.shrinkage);
|
ChannelStorage storage(image, fld.shrinkage);
|
||||||
|
|
||||||
@ -537,4 +530,49 @@ void cv::SCascade::detect(const Mat& image, const std::vector<cv::Rect>& /*rois*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cv::SCascade::detect(cv::InputArray _image, cv::InputArray _rois, std::vector<Detection>& objects) const
|
||||||
|
{
|
||||||
|
// only color images are supperted
|
||||||
|
cv::Mat image = _image.getMat();
|
||||||
|
CV_Assert(image.type() == CV_8UC3);
|
||||||
|
|
||||||
|
Filds& fld = *filds;
|
||||||
|
fld.calcLevels(image.size(), scales);
|
||||||
|
|
||||||
|
objects.clear();
|
||||||
|
|
||||||
|
if (_rois.kind() == cv::_InputArray::NONE)
|
||||||
|
return detectNoRoi(image, objects);
|
||||||
|
|
||||||
|
cv::Mat roi = _rois.getMat();
|
||||||
|
cv::Mat mask(image.rows / fld.shrinkage, image.cols / fld.shrinkage, CV_8UC1);
|
||||||
|
|
||||||
|
mask.setTo(cv::Scalar::all(0));
|
||||||
|
cv::Rect* r = roi.ptr<cv::Rect>(0);
|
||||||
|
for (int i = 0; i < (int)roi.cols; ++i)
|
||||||
|
cv::Mat(mask, cv::Rect(r[i].x / fld.shrinkage, r[i].y / fld.shrinkage, r[i].width / fld.shrinkage , r[i].height / fld.shrinkage)).setTo(cv::Scalar::all(1));
|
||||||
|
|
||||||
|
// create integrals
|
||||||
|
ChannelStorage storage(image, fld.shrinkage);
|
||||||
|
|
||||||
|
typedef std::vector<Level>::const_iterator lIt;
|
||||||
|
for (lIt it = fld.levels.begin(); it != fld.levels.end(); ++it)
|
||||||
|
{
|
||||||
|
const Level& level = *it;
|
||||||
|
|
||||||
|
for (int dy = 0; dy < level.workRect.height; ++dy)
|
||||||
|
{
|
||||||
|
uchar* m = mask.ptr<uchar>(dy);
|
||||||
|
for (int dx = 0; dx < level.workRect.width; ++dx)
|
||||||
|
{
|
||||||
|
if (m[dx])
|
||||||
|
{
|
||||||
|
storage.offset = dy * storage.step + dx;
|
||||||
|
fld.detectAt(dx, dy, level, storage, objects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -63,36 +63,96 @@ TEST(SCascade, detect)
|
|||||||
cv::Mat colored = cv::imread(cvtest::TS::ptr()->get_data_path() + "cascadeandhog/bahnhof/image_00000000_0.png");
|
cv::Mat colored = cv::imread(cvtest::TS::ptr()->get_data_path() + "cascadeandhog/bahnhof/image_00000000_0.png");
|
||||||
ASSERT_FALSE(colored.empty());
|
ASSERT_FALSE(colored.empty());
|
||||||
|
|
||||||
|
std::vector<Detection> objects;
|
||||||
|
|
||||||
|
cascade.detect(colored, cv::noArray(), objects);
|
||||||
|
|
||||||
|
// cv::Mat out = colored.clone();
|
||||||
|
// int level = 0, total = 0;
|
||||||
|
// int levelWidth = objects[0].bb.width;
|
||||||
|
|
||||||
|
// for(int i = 0 ; i < (int)objects.size(); ++i)
|
||||||
|
// {
|
||||||
|
// if (objects[i].bb.width != levelWidth)
|
||||||
|
// {
|
||||||
|
// std::cout << "Level: " << level << " total " << total << std::endl;
|
||||||
|
// cv::imshow("out", out);
|
||||||
|
// cv::waitKey(0);
|
||||||
|
// out = colored.clone();
|
||||||
|
// levelWidth = objects[i].bb.width;
|
||||||
|
// total = 0;
|
||||||
|
// level++;
|
||||||
|
// }
|
||||||
|
// cv::rectangle(out, objects[i].bb, cv::Scalar(255, 0, 0, 255), 1);
|
||||||
|
// std::cout << "detection: " << objects[i].bb.x
|
||||||
|
// << " " << objects[i].bb.y
|
||||||
|
// << " " << objects[i].bb.width
|
||||||
|
// << " " << objects[i].bb.height << std::endl;
|
||||||
|
// total++;
|
||||||
|
// }
|
||||||
|
// std::cout << "detected: " << (int)objects.size() << std::endl;
|
||||||
|
ASSERT_EQ((int)objects.size(), 3498);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SCascade, detectRoi)
|
||||||
|
{
|
||||||
|
typedef cv::SCascade::Detection Detection;
|
||||||
|
std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/sc_cvpr_2012_to_opencv.xml";
|
||||||
|
cv::SCascade cascade;
|
||||||
|
cv::FileStorage fs(xml, cv::FileStorage::READ);
|
||||||
|
ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode()));
|
||||||
|
|
||||||
|
cv::Mat colored = cv::imread(cvtest::TS::ptr()->get_data_path() + "cascadeandhog/bahnhof/image_00000000_0.png");
|
||||||
|
ASSERT_FALSE(colored.empty());
|
||||||
|
|
||||||
std::vector<Detection> objects;
|
std::vector<Detection> objects;
|
||||||
std::vector<cv::Rect> rois;
|
std::vector<cv::Rect> rois;
|
||||||
rois.push_back(cv::Rect(0, 0, 640, 480));
|
rois.push_back(cv::Rect(0, 0, 640, 480));
|
||||||
|
|
||||||
cascade.detect(colored, rois, objects);
|
cascade.detect(colored, rois, objects);
|
||||||
|
|
||||||
|
// cv::Mat out = colored.clone();
|
||||||
|
// int level = 0, total = 0;
|
||||||
|
// int levelWidth = objects[0].bb.width;
|
||||||
|
|
||||||
cv::Mat out = colored.clone();
|
// for(int i = 0 ; i < (int)objects.size(); ++i)
|
||||||
int level = 0, total = 0;
|
// {
|
||||||
int levelWidth = objects[0].bb.width;
|
// if (objects[i].bb.width != levelWidth)
|
||||||
|
// {
|
||||||
for(int i = 0 ; i < (int)objects.size(); ++i)
|
// std::cout << "Level: " << level << " total " << total << std::endl;
|
||||||
{
|
// cv::imshow("out", out);
|
||||||
if (objects[i].bb.width != levelWidth)
|
// cv::waitKey(0);
|
||||||
{
|
// out = colored.clone();
|
||||||
std::cout << "Level: " << level << " total " << total << std::endl;
|
// levelWidth = objects[i].bb.width;
|
||||||
cv::imshow("out", out);
|
// total = 0;
|
||||||
cv::waitKey(0);
|
// level++;
|
||||||
out = colored.clone();
|
// }
|
||||||
levelWidth = objects[i].bb.width;
|
// cv::rectangle(out, objects[i].bb, cv::Scalar(255, 0, 0, 255), 1);
|
||||||
total = 0;
|
// std::cout << "detection: " << objects[i].bb.x
|
||||||
level++;
|
// << " " << objects[i].bb.y
|
||||||
}
|
// << " " << objects[i].bb.width
|
||||||
cv::rectangle(out, objects[i].bb, cv::Scalar(255, 0, 0, 255), 1);
|
// << " " << objects[i].bb.height << std::endl;
|
||||||
std::cout << "detection: " << objects[i].bb.x
|
// total++;
|
||||||
<< " " << objects[i].bb.y
|
// }
|
||||||
<< " " << objects[i].bb.width
|
// std::cout << "detected: " << (int)objects.size() << std::endl;
|
||||||
<< " " << objects[i].bb.height << std::endl;
|
|
||||||
total++;
|
|
||||||
}
|
|
||||||
std::cout << "detected: " << (int)objects.size() << std::endl;
|
|
||||||
ASSERT_EQ((int)objects.size(), 3498);
|
ASSERT_EQ((int)objects.size(), 3498);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SCascade, detectNoRoi)
|
||||||
|
{
|
||||||
|
typedef cv::SCascade::Detection Detection;
|
||||||
|
std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/sc_cvpr_2012_to_opencv.xml";
|
||||||
|
cv::SCascade cascade;
|
||||||
|
cv::FileStorage fs(xml, cv::FileStorage::READ);
|
||||||
|
ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode()));
|
||||||
|
|
||||||
|
cv::Mat colored = cv::imread(cvtest::TS::ptr()->get_data_path() + "cascadeandhog/bahnhof/image_00000000_0.png");
|
||||||
|
ASSERT_FALSE(colored.empty());
|
||||||
|
|
||||||
|
std::vector<Detection> objects;
|
||||||
|
std::vector<cv::Rect> rois;
|
||||||
|
|
||||||
|
cascade.detect(colored, rois, objects);
|
||||||
|
|
||||||
|
ASSERT_EQ((int)objects.size(), 0);
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user