Some predefined neighborhood configurations
Some classical displacements around a current iterator are stored in static arrays. They are defined in the file neighbors.hpp . By the way, classical image processing neighborhood functors have been defined to get either a std::vector of the iterators (1d, 2d, 3d or 4d) of the neighbors of the current iterator (1d, 2d, 3d or 4d) either a std::vector of the values of the neighbors of the current iterator (1d, 2d, 3d or 4d). For each neighborhood configuration, a safe and an unsafe functor version are given. The safe version returns only existing neighbors. It permits to avoid the boring problem of image borders treatment. The unsafe version always returns the same number of neighbors. Consequently, it should be used with care. Nevertheless as no tests are done to verify that the neighbors are in the image are, computations should be faster than with safe functors. The main advantage of using functors is that you can write a same generic algorithm for various dimension and neighborhood configurations. You can even imagine to use the algorithm on a graph modeling your image on the condition to have defined a functor providing the neighbors of you current element on the graph. For that you have to follow the skeleton of the functors defined in neighborhood.hpp In the following, we give a description of these neighborhood configurations:
1d and 2d neighborhoods
Here are some functor to get the neighbors's iterators or values of a current iterator (1d or 2d).
3d neighborhood
Here are some functor to get the neighbors 3d iterators or values of a current 3d iterator:
6-connexity neighbors (slip::n_6c)
18-connexity neighbors (slip::n_18c)
26-connexity neighbors (slip::n_26c)
4d neighborhood
Here are some functor to get the neighbors 4d iterators or values of a current 4d iterator:
Some predefined successor and predecessor configuration
2d previous and next neighbors
Previous 4-connexity
Next 4-connexity
Previous 8-connexity
Next 8-connexity
Previous odd pseudohexgonal
Next odd pseudohexgonal
Previous even pseudohexgonal
Next even pseudohexgonal
3d previous and next neighbors
4d previous and next neighbors
Various ways to get neighbors
3x3 Median filtering using double loop and box
3x3 Median filtering unsing iterators and neighborhood functors
template<typename Iterator1,
typename Iterator2,
typename NeighborFunc>
void median_filter_direct(Iterator1 in_first, Iterator1 in_last,
Iterator2 out_first, Iterator2 out_last,
NeighborFunc N)
{
typedef typename std::iterator_traits<Iterator1>::value_type value_type;
std::vector<value_type> neighbors(26);
for(; in_first != in_last; ++in_first, ++out_first)
{
N(in_first,neighbors);
neighbors.push_back(*in_first);
*out_first = *
slip::median(neighbors.begin(),neighbors.end());
}
}
typedef double T;
I.read(args[2]);
const std::size_t rows = I.
rows();
const std::size_t cols = I.
cols();
Median.upper_left(),Median.bottom_right(),
Neigh);
Median.write(args[4]);
typedef double T;
I.read(args[2]);
const std::size_t rows = I.
rows();
const std::size_t cols = I.
cols();
const int bsize = 1;
Iborder.write("Iborder.png");
Median.upper_left(),Median.bottom_right(),
Neigh);
Median.write(args[4]);
3x3 Median filtering unsing indirect iterators and neighborhood functors
template<typename Iterator1,
typename Iterator2,
typename NeighborFunc>
void median_filter_indirect(Iterator1 in_first, Iterator1 in_last,
Iterator2 out_first, Iterator2 out_last,
NeighborFunc N)
{
typedef typename std::iterator_traits<Iterator1>::value_type value_type;
std::vector<Iterator1> neighbors(26);
for(; in_first != in_last; ++in_first, ++out_first)
{
N(in_first,neighbors);
neighbors.push_back(in_first);
boost::indirect_iterator<typename std::vector<Iterator1>::iterator,
typename std::vector<value_type>::value_type>
indirect_first(neighbors.begin()),
indirect_last(neighbors.end());
assert(indirect_first != indirect_last);
}
}
typedef double T;
I.read(args[2]);
const std::size_t rows = I.
rows();
const std::size_t cols = I.
cols();
Median.upper_left(),Median.bottom_right(),
Neigh);
Median.write(args[4]);
3x3 Median filtering unsing iterators, neighborhood functors and a local median process functor
- The local median process functor
struct median_func
{
template <typename RandomAccessIterator>
typename std::iterator_traits<RandomAccessIterator>::value_type
operator()(RandomAccessIterator first, RandomAccessIterator last) const
{
}
};
- The median algorithm
template<typename Iterator1,
typename Iterator2,
typename NeighborFunc,
typename NeighborProcess>
void median_filter_direct(Iterator1 in_first, Iterator1 in_last,
Iterator2 out_first, Iterator2 out_last,
NeighborFunc N,
NeighborProcess NP)
{
typedef typename std::iterator_traits<Iterator1>::value_type value_type;
std::vector<value_type> neighbors(26);
for(; in_first != in_last; ++in_first, ++out_first)
{
N(in_first,neighbors);
neighbors.push_back(*in_first);
*out_first = NP(neighbors.begin(),neighbors.end());
}
}
- Call of the median algorithm
typedef double T;
I.read(args[2]);
const std::size_t rows = I.
rows();
const std::size_t cols = I.
cols();
max_func LocalProcess;
Median.upper_left(),Median.bottom_right(),
Neigh,
LocalProcess);
Median.write(args[4]);