// Copyright (C) 2011 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#undef DLIB_LABEL_CONNeCTED_BLOBS_ABSTRACT_H_
#ifdef DLIB_LABEL_CONNeCTED_BLOBS_ABSTRACT_H_
#include "../geometry.h"
#include <vector>
#include "../image_processing/generic_image.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
struct neighbors_8
{
/*!
WHAT THIS OBJECT REPRESENTS
This object is a pixel neighborhood generating functor for
use with the label_connected_blobs() routine defined below.
!*/
void operator() (
const point& p,
std::vector<point>& neighbors
) const;
/*!
ensures
- adds the 8 neighboring pixels surrounding p into neighbors
!*/
};
struct neighbors_4
{
/*!
WHAT THIS OBJECT REPRESENTS
This object is a pixel neighborhood generating functor for
use with the label_connected_blobs() routine defined below.
!*/
void operator() (
const point& p,
std::vector<point>& neighbors
) const;
/*!
ensures
- adds the 4 neighboring pixels of p into neighbors. These
are the ones immediately to the left, top, right, and bottom.
!*/
};
// ----------------------------------------------------------------------------------------
struct connected_if_both_not_zero
{
/*!
WHAT THIS OBJECT REPRESENTS
This object is a pixel connection testing functor for use
with the label_connected_blobs() routine defined below.
!*/
template <typename image_view_type>
bool operator() (
const image_view_type& img,
const point& a,
const point& b
) const
{
return (img[a.y()][a.x()] != 0 && img[b.y()][b.x()] != 0);
}
};
struct connected_if_equal
{
/*!
WHAT THIS OBJECT REPRESENTS
This object is a pixel connection testing functor for use
with the label_connected_blobs() routine defined below.
!*/
template <typename image_view_type>
bool operator() (
const image_view_type& img,
const point& a,
const point& b
) const
{
return (img[a.y()][a.x()] == img[b.y()][b.x()]);
}
};
// ----------------------------------------------------------------------------------------
struct zero_pixels_are_background
{
/*!
WHAT THIS OBJECT REPRESENTS
This object is a background testing functor for use
with the label_connected_blobs() routine defined below.
!*/
template <typename image_view_type>
bool operator() (
const image_view_type& img,
const point& p
) const
{
return img[p.y()][p.x()] == 0;
}
};
struct nothing_is_background
{
/*!
WHAT THIS OBJECT REPRESENTS
This object is a background testing functor for use
with the label_connected_blobs() routine defined below.
!*/
template <typename image_view_type>
bool operator() (
const image_view_type&,
const point&
) const
{
return false;
}
};
// ----------------------------------------------------------------------------------------
template <
typename image_type,
typename label_image_type,
typename background_functor_type,
typename neighbors_functor_type,
typename connected_functor_type
>
unsigned long label_connected_blobs (
const image_type& img,
const background_functor_type& is_background,
const neighbors_functor_type& get_neighbors,
const connected_functor_type& is_connected,
label_image_type& label_img
);
/*!
requires
- image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- label_image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h and it must contain integer pixels.
- is_background(img, point(c,r)) is a legal expression that evaluates to a bool.
- is_connected(img, point(c,r), point(c2,r2)) is a legal expression that
evaluates to a bool.
- get_neighbors(point(c,r), neighbors) is a legal expression where neighbors
is of type std::vector<point>.
- is_same_object(img, label_img) == false
ensures
- This function labels each of the connected blobs in img with a unique integer
label.
- An image can be thought of as a graph where pixels A and B are connected if
and only if the following two statements are satisfied:
- is_connected(img,A,B) == true
- get_neighbors(A, neighbors) results in neighbors containing B or
get_neighbors(B, neighbors) results in neighbors containing A.
Then this function can be understood as labeling all the connected components
of this pixel graph such that all pixels in a component get the same label while
pixels in different components get different labels. Note that there is a
special "background" component determined by is_background(). Any pixels which
are "background" always get a blob id of 0 regardless of any other considerations.
- #label_img.nr() == img.nr()
- #label_img.nc() == img.nc()
- for all valid r and c:
- #label_img[r][c] == the blob label number for pixel img[r][c].
- #label_img[r][c] >= 0
- if (is_background(img, point(c,r))) then
- #label_img[r][c] == 0
- else
- #label_img[r][c] != 0
- if (img.size() != 0) then
- returns max(mat(#label_img))+1
(i.e. returns a number one greater than the maximum blob id number,
this is the number of blobs found.)
- else
- returns 0
- blob labels are contiguous, therefore, the number returned by this function is
the number of blobs in the image (including the background blob).
- It is guaranteed that is_connected() and is_background() will never be
called with points outside the image.
!*/
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_LABEL_CONNeCTED_BLOBS_ABSTRACT_H_