I want to search for a small image from a large one, my algorithm is:
I want to use boost::algorithm::boyer_moore to do the line searching, it works fine with std::string:
#include <string>
using namespace std;
#include "boost/algorithm/searching/boyer_moore.hpp"
using namespace boost::algorithm;
int main() {
string s;
boyer_moore<string::iterator> bm(s.begin(), s.end()); // it compiles
}
the code compiles, but this one not:
#include "boost/mpl/vector.hpp"
using namespace boost;
#include "boost/gil/gil_all.hpp"
using namespace boost::gil;
#include "boost/algorithm/searching/boyer_moore.hpp"
using namespace boost::algorithm;
int main() {
typedef rgba8_image_t image_t;
typedef image_t::view_t view_t;
view_t vw;
boyer_moore<view_t::x_iterator> bm(vw.row_begin(0), vw.row_end(0)); // compile error
}
Both of them are iterators, what's wrong with the second one?
Thanks.
According to the docs the algorithm uses an auxiliary data structure called skip_table
. By default (when the value_type
of the iterator is not a char or unsigned char) this table uses a tr1::unordered_map
, and this requires that gil::pixel
be hash-able. So you have two options: you either change the default skip_table by specializing BM_traits
for your iterator (this is sadly undocumented), or you make gil::pixel
hash-able. For the latter you can create a std::size_t hash_value(pixel<ChannelValue,Layout> const& val)
inside the namespace boost::gil
. The following compiles with g++ 4.9.0 and Visual Studio 2013 (and does nothing):
#include <boost/functional/hash.hpp> //ADDED
#include <boost/mpl/vector.hpp>
#include <boost/gil/gil_all.hpp>
#include <boost/algorithm/searching/boyer_moore.hpp>
using namespace boost;
using namespace boost::gil;
using namespace boost::algorithm;
namespace boost {
namespace gil
{
template <typename ChannelValue, typename Layout>
std::size_t hash_value(pixel<ChannelValue, Layout> const& b)
{
std::size_t seed = 0;
for (int c = 0; c<num_channels<pixel<ChannelValue, Layout> >::value; ++c)
hash_combine(seed, b[c]);
return seed;
}
}
}
namespace std { //ADDED
template <typename ChannelValue, typename Layout>
struct hash<boost::gil::pixel<ChannelValue,Layout> > {
size_t operator ()(boost::gil::pixel<ChannelValue, Layout> const& value) const {
return hash_value(value);
}
};
}
int main() {
typedef rgba8_image_t image_t;
typedef image_t::view_t view_t;
view_t vw;
boyer_moore<view_t::x_iterator> bm(vw.row_begin(0), vw.row_end(0)); // compile error
}