Filled out spec for find_candidate_object_locations()

This commit is contained in:
Davis King 2013-03-24 10:57:40 -04:00
parent b638145fb6
commit a924bdad61
2 changed files with 83 additions and 7 deletions

View File

@ -617,12 +617,15 @@ namespace dlib
const unsigned long min_size = 20,
const unsigned long max_merging_iterations = 50
)
/*!
requires
- is_vector(kvals) == true
- kvals.size() > 0
!*/
{
// make sure requires clause is not broken
DLIB_ASSERT(is_vector(kvals) && kvals.size() > 0,
"\t void find_candidate_object_locations()"
<< "\n\t Invalid inputs were given to this function."
<< "\n\t is_vector(kvals): " << is_vector(kvals)
<< "\n\t kvals.size(): " << kvals.size()
);
typedef dlib::memory_manager<char>::kernel_2c mm_type;
typedef dlib::set<rectangle, mm_type>::kernel_1a set_of_rects;
@ -652,8 +655,14 @@ namespace dlib
rects.insert(rects.end(), working_rects.begin(), working_rects.end());
// now iteratively merge all the rectangles we have and record the results
// Now iteratively merge all the rectangles we have and record the results.
// Note that, unlike what is described in the paper
// Segmentation as Selective Search for Object Recognition" by Koen E. A. van de Sande, et al.
// we don't use any kind of histogram/SIFT like thing to order the edges
// between the blobs. Here we simply order by the pixel difference value.
// Additionally, note that we keep progressively merging boxes in the outer
// loop rather than performing just a single iteration as indicated in the
// paper.
set_of_rects detected_rects;
bool did_merge = true;
for (unsigned long iter = 0; did_merge && iter < max_merging_iterations; ++iter)
@ -661,6 +670,8 @@ namespace dlib
did_merge = false;
sets.clear();
sets.set_size(working_rects.size());
// recursively merge neighboring blobs until we have merged everything
for (unsigned long i = 0; i < edges.size(); ++i)
{
edge_data temp = edges[i];
@ -670,6 +681,9 @@ namespace dlib
if (temp.set1 != temp.set2)
{
rectangle merged_rect = working_rects[temp.set1] + working_rects[temp.set2];
// Skip merging this pair of blobs if it was merged in a previous
// iteration. Doing this lets us consider other possible blob
// merges.
if (!detected_rects.is_member(merged_rect))
{
const unsigned long new_set = sets.merge_sets(temp.set1, temp.set2);

View File

@ -3,6 +3,9 @@
#undef DLIB_SEGMENT_ImAGE_ABSTRACT_H__
#ifdef DLIB_SEGMENT_ImAGE_ABSTRACT_H__
#include <vector>
#include "../matrix.h"
namespace dlib
{
@ -45,6 +48,65 @@ namespace dlib
case the entire image will be put into a single segment).
!*/
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
typename in_image_type,
typename EXP
>
void find_candidate_object_locations (
const in_image_type& in_img,
std::vector<rectangle>& rects,
const matrix_exp<EXP>& kvals = linspace(50, 200, 3),
const unsigned long min_size = 20,
const unsigned long max_merging_iterations = 50
);
/*!
requires
- is_vector(kvals) == true
- kvals.size() > 0
ensures
- This function takes an input image and generates a set of candidate
rectangles which are expected to bound any objects in the image. It does
this by running a version of the segment_image() routine on the image and
then reports rectangles containing each of the segments as well as rectangles
containing unions of adjacent segments. The basic idea is described in the
paper:
Segmentation as Selective Search for Object Recognition by Koen E. A. van de Sande, et al.
Note that this function deviates from what is described in the paper slightly.
See the code for details.
- The basic segmentation is performed kvals.size() times, each time with the k
parameter (see segment_image() and the Felzenszwalb paper for details on k)
set to a different value from kvals.
- All the rectangles output by this function will have an area >= min_size.
- There are max_merging_iterations rounds of neighboring blob merging.
Therefore, this parameter has some effect on the number of output rectangles
you get, with larger values of the parameter giving more output rectangles.
- This function appends the output rectangles into #rects. This means that any
rectangles in rects before this function was called will still be in there
after it terminates. Note further that #rects will not contain any duplicate
rectangles. That is, for all valid i and j where i != j it will be true
that:
- #rects[i] != rects[j]
!*/
// ----------------------------------------------------------------------------------------
template <
typename alloc
>
void remove_duplicates (
std::vector<rectangle,alloc>& rects
);
/*!
ensures
- This function finds any duplicate rectangles in rects and removes the extra
instances. This way, the result is that rects contains only unique rectangle
instances.
!*/
// ----------------------------------------------------------------------------------------
}