+ handle boundary cases in 3x3 convolution
This commit is contained in:
parent
557f69314f
commit
fb34c7ef5a
1 changed files with 204 additions and 87 deletions
|
@ -196,7 +196,11 @@ void process_channel (Src const& src, Dst & dst, mapnik::filter::sobel)
|
||||||
template <typename Src, typename Dst, typename FilterTag>
|
template <typename Src, typename Dst, typename FilterTag>
|
||||||
void apply_convolution_3x3(Src const& src_view, Dst & dst_view, FilterTag filter_tag)
|
void apply_convolution_3x3(Src const& src_view, Dst & dst_view, FilterTag filter_tag)
|
||||||
{
|
{
|
||||||
typename Src::xy_locator src_loc = src_view.xy_at(1,1);
|
// p0 p1 p2
|
||||||
|
// p3 p4 p5
|
||||||
|
// p6 p7 p8
|
||||||
|
|
||||||
|
typename Src::xy_locator src_loc = src_view.xy_at(0,0);
|
||||||
typename Src::xy_locator::cached_location_t loc00 = src_loc.cache_location(-1,-1);
|
typename Src::xy_locator::cached_location_t loc00 = src_loc.cache_location(-1,-1);
|
||||||
typename Src::xy_locator::cached_location_t loc10 = src_loc.cache_location( 0,-1);
|
typename Src::xy_locator::cached_location_t loc10 = src_loc.cache_location( 0,-1);
|
||||||
typename Src::xy_locator::cached_location_t loc20 = src_loc.cache_location( 1,-1);
|
typename Src::xy_locator::cached_location_t loc20 = src_loc.cache_location( 1,-1);
|
||||||
|
@ -207,34 +211,147 @@ void apply_convolution_3x3(Src const& src_view, Dst & dst_view, FilterTag filter
|
||||||
typename Src::xy_locator::cached_location_t loc12 = src_loc.cache_location( 0, 1);
|
typename Src::xy_locator::cached_location_t loc12 = src_loc.cache_location( 0, 1);
|
||||||
typename Src::xy_locator::cached_location_t loc22 = src_loc.cache_location( 1, 1);
|
typename Src::xy_locator::cached_location_t loc22 = src_loc.cache_location( 1, 1);
|
||||||
|
|
||||||
|
typename Src::x_iterator dst_it = dst_view.row_begin(0);
|
||||||
|
|
||||||
|
// top row
|
||||||
|
for (int x = 0 ; x < src_view.width(); ++x)
|
||||||
|
{
|
||||||
|
*dst_it = src_loc[loc11];
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
bits32f p[9];
|
||||||
|
|
||||||
|
p[4] = src_loc[loc11][i];
|
||||||
|
p[7] = src_loc[loc12][i];
|
||||||
|
|
||||||
|
if (x == 0)
|
||||||
|
{
|
||||||
|
p[3] = p[4];
|
||||||
|
p[6] = p[7];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p[3] = src_loc[loc01][i];
|
||||||
|
p[6] = src_loc[loc02][i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( x == src_view.width()-1)
|
||||||
|
{
|
||||||
|
p[5] = p[4];
|
||||||
|
p[8] = p[7];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p[5] = src_loc[loc21][i];
|
||||||
|
p[8] = src_loc[loc22][i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
p[0] = p[6];
|
||||||
|
p[1] = p[7];
|
||||||
|
p[2] = p[8];
|
||||||
|
|
||||||
|
process_channel(p, (*dst_it)[i], filter_tag);
|
||||||
|
}
|
||||||
|
++src_loc.x();
|
||||||
|
++dst_it;
|
||||||
|
}
|
||||||
|
// carrige-return
|
||||||
|
src_loc += point2<std::ptrdiff_t>(-src_view.width(),1);
|
||||||
|
|
||||||
|
// 1... height-1 rows
|
||||||
for (int y = 1; y<src_view.height()-1; ++y)
|
for (int y = 1; y<src_view.height()-1; ++y)
|
||||||
{
|
{
|
||||||
typename Src::x_iterator dst_it = dst_view.row_begin(y);
|
for (int x = 0; x < src_view.width(); ++x)
|
||||||
for (int x = 0; x<src_view.width(); ++x)
|
|
||||||
{
|
{
|
||||||
*dst_it = src_loc[loc11];
|
*dst_it = src_loc[loc11];
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
bits32f p[9];
|
bits32f p[9];
|
||||||
p[0] = src_loc[loc00][i];
|
|
||||||
p[1] = src_loc[loc10][i];
|
p[1] = src_loc[loc10][i];
|
||||||
p[2] = src_loc[loc20][i];
|
|
||||||
p[3] = src_loc[loc01][i];
|
|
||||||
p[4] = src_loc[loc11][i];
|
p[4] = src_loc[loc11][i];
|
||||||
p[5] = src_loc[loc21][i];
|
|
||||||
p[6] = src_loc[loc02][i];
|
|
||||||
p[7] = src_loc[loc12][i];
|
p[7] = src_loc[loc12][i];
|
||||||
p[8] = src_loc[loc22][i];
|
|
||||||
|
if (x == 0)
|
||||||
|
{
|
||||||
|
p[0] = p[1];
|
||||||
|
p[3] = p[4];
|
||||||
|
p[6] = p[7];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p[0] = src_loc[loc00][i];
|
||||||
|
p[3] = src_loc[loc01][i];
|
||||||
|
p[6] = src_loc[loc02][i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( x == src_view.width() - 1)
|
||||||
|
{
|
||||||
|
p[2] = p[1];
|
||||||
|
p[5] = p[4];
|
||||||
|
p[8] = p[7];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p[2] = src_loc[loc20][i];
|
||||||
|
p[5] = src_loc[loc21][i];
|
||||||
|
p[8] = src_loc[loc22][i];
|
||||||
|
}
|
||||||
process_channel(p, (*dst_it)[i], filter_tag);
|
process_channel(p, (*dst_it)[i], filter_tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
++dst_it;
|
++dst_it;
|
||||||
++src_loc.x();
|
++src_loc.x();
|
||||||
}
|
}
|
||||||
|
// carrige-return
|
||||||
src_loc += point2<std::ptrdiff_t>(-src_view.width(),1);
|
src_loc += point2<std::ptrdiff_t>(-src_view.width(),1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
// bottom row
|
||||||
|
//src_loc = src_view.xy_at(0,src_view.height()-1);
|
||||||
|
for (int x = 0 ; x < src_view.width(); ++x)
|
||||||
|
{
|
||||||
|
*dst_it = src_loc[loc11];
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
bits32f p[9];
|
||||||
|
|
||||||
|
p[1] = src_loc[loc10][i];
|
||||||
|
p[4] = src_loc[loc11][i];
|
||||||
|
|
||||||
|
if (x == 0)
|
||||||
|
{
|
||||||
|
p[0] = p[1];
|
||||||
|
p[3] = p[4];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p[0] = src_loc[loc00][i];
|
||||||
|
p[3] = src_loc[loc01][i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( x == src_view.width()-1)
|
||||||
|
{
|
||||||
|
p[2] = p[1];
|
||||||
|
p[5] = p[4];
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p[2] = src_loc[loc20][i];
|
||||||
|
p[5] = src_loc[loc21][i];
|
||||||
|
}
|
||||||
|
|
||||||
|
p[6] = p[0];
|
||||||
|
p[7] = p[1];
|
||||||
|
p[8] = p[2];
|
||||||
|
|
||||||
|
process_channel(p, (*dst_it)[i], filter_tag);
|
||||||
|
}
|
||||||
|
++src_loc.x();
|
||||||
|
++dst_it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Src, typename Dst,typename FilterTag>
|
template <typename Src, typename Dst,typename FilterTag>
|
||||||
void apply_filter(Src const& src, Dst & dst, FilterTag filter_tag)
|
void apply_filter(Src const& src, Dst & dst, FilterTag filter_tag)
|
||||||
|
@ -368,7 +485,7 @@ template <typename Src>
|
||||||
struct filter_visitor : boost::static_visitor<void>
|
struct filter_visitor : boost::static_visitor<void>
|
||||||
{
|
{
|
||||||
filter_visitor(Src & src)
|
filter_visitor(Src & src)
|
||||||
: src_(src) {}
|
: src_(src) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void operator () (T filter_tag)
|
void operator () (T filter_tag)
|
||||||
|
|
Loading…
Reference in a new issue