|
Shinya Kitaoka |
810553 |
#pragma once
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifndef TCG_IMAGE_OPS_HPP
|
|
Toshihiro Shimizu |
890ddd |
#define TCG_IMAGE_OPS_HPP
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// tcg includes
|
|
Toshihiro Shimizu |
890ddd |
#include "../image_ops.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "../pixel.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "../unique_ptr.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// STD includes
|
|
Toshihiro Shimizu |
890ddd |
#include <assert.h></assert.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <memory></memory>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace tcg {
|
|
Shinya Kitaoka |
120a6e |
namespace image_ops {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//**************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Flat Blur implementation
|
|
Toshihiro Shimizu |
890ddd |
//**************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename pixsum="" ptrin,="" ptrout,="" typename=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
void _flatFilterLine(PtrIn in, PtrOut out, int lx, int addIn, int addOut,
|
|
Shinya Kitaoka |
120a6e |
int radius, PixSum *sums) {
|
|
Shinya Kitaoka |
120a6e |
typedef typename std::iterator_traits<ptrin> trIn;</ptrin>
|
|
Shinya Kitaoka |
120a6e |
typedef typename trIn::value_type pixIn_type;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
struct locals {
|
|
Shinya Kitaoka |
120a6e |
inline static void fillSums(int lx, int radius, PtrIn lineIn,
|
|
Shinya Kitaoka |
120a6e |
PixSum *pixsum, int addIn, int addSum) {
|
|
Shinya Kitaoka |
120a6e |
using namespace pixel_ops;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
PtrIn newPixIn = lineIn;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
PixSum sum;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Build up to radius pixels adding new pixels only
|
|
Shinya Kitaoka |
120a6e |
int x, xNew, xEnd = tmin(radius, lx);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (xNew = 0; xNew != xEnd; ++xNew, newPixIn += addIn)
|
|
Shinya Kitaoka |
120a6e |
sum = sum + *newPixIn;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Store sums AND add new pixels. Observe that the current pixel value is
|
|
Shinya Kitaoka |
120a6e |
// decreased
|
|
Shinya Kitaoka |
120a6e |
// BEFORE storage. This makes this function "strict" in calculating the
|
|
Shinya Kitaoka |
120a6e |
// sums.
|
|
Shinya Kitaoka |
120a6e |
for (x = 0; xNew != lx;
|
|
Shinya Kitaoka |
120a6e |
++x, ++xNew, lineIn += addIn, newPixIn += addIn, pixsum += addSum) {
|
|
Shinya Kitaoka |
120a6e |
sum = (sum + *newPixIn) - *lineIn;
|
|
Shinya Kitaoka |
120a6e |
*pixsum = *pixsum + sum;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Finally, without adding new pixels
|
|
Shinya Kitaoka |
120a6e |
for (; x != lx; ++x, lineIn += addIn, pixsum += addSum) {
|
|
Shinya Kitaoka |
120a6e |
sum = sum - *lineIn;
|
|
Shinya Kitaoka |
120a6e |
*pixsum = *pixsum + sum;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
memset(sums, 0, lx * sizeof(PixSum));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Add *strict* halves of the convolution sums
|
|
Shinya Kitaoka |
120a6e |
locals::fillSums(lx, radius, in, sums, addIn,
|
|
Shinya Kitaoka |
120a6e |
1); // Right part of the convolution
|
|
Shinya Kitaoka |
120a6e |
locals::fillSums(lx, radius, in + addIn * (lx - 1), sums + lx - 1, -addIn,
|
|
Shinya Kitaoka |
120a6e |
-1); // Left ...
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Normalize sums
|
|
Shinya Kitaoka |
120a6e |
int diameter = 2 * radius + 1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int x = 0; x != lx; ++x, in += addIn, out += addOut, ++sums) {
|
|
Shinya Kitaoka |
120a6e |
using namespace pixel_ops;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
pixIn_type pix(*in);
|
|
Shinya Kitaoka |
120a6e |
pixel_ops::assign(
|
|
Shinya Kitaoka |
120a6e |
pix, (*sums + pix) / diameter); // Note that *in is added, due *strict*
|
|
Shinya Kitaoka |
120a6e |
// halving the sums above
|
|
Shinya Kitaoka |
120a6e |
*out = pix;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
template
|
|
Shinya Kitaoka |
120a6e |
typename SelectorFunc>
|
|
Toshihiro Shimizu |
890ddd |
void _flatFilterLine(PtrIn in, PtrOut out, int lx, int addIn, int addOut,
|
|
Shinya Kitaoka |
120a6e |
SelectorFunc selector, int radius, PixSum *sums,
|
|
Shinya Kitaoka |
120a6e |
int *counts) {
|
|
Shinya Kitaoka |
120a6e |
typedef typename std::iterator_traits<ptrin> trIn;</ptrin>
|
|
Shinya Kitaoka |
120a6e |
typedef typename trIn::value_type pixIn_type;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
struct locals {
|
|
Shinya Kitaoka |
120a6e |
inline static void fillSums(int lx, int radius, PtrIn lineIn,
|
|
Shinya Kitaoka |
120a6e |
PixSum *pixsum, int *pixcount, int addIn,
|
|
Shinya Kitaoka |
120a6e |
int addSum, SelectorFunc selector) {
|
|
Shinya Kitaoka |
120a6e |
using namespace pixel_ops;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PtrIn newPixIn = lineIn;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PixSum sum;
|
|
Shinya Kitaoka |
120a6e |
int count = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Build up to radius pixels adding new pixels only
|
|
Shinya Kitaoka |
120a6e |
int x, xNew, xEnd = tmin(radius, lx);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (xNew = 0; xNew != xEnd; ++xNew, newPixIn += addIn) {
|
|
Shinya Kitaoka |
120a6e |
const pixIn_type &npi = *newPixIn;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (selector(npi)) sum = sum + npi, ++count;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Store sums AND add new pixels. Observe that the current pixel value is
|
|
Shinya Kitaoka |
120a6e |
// decreased
|
|
Shinya Kitaoka |
120a6e |
// BEFORE storage. This makes this function "strict" in calculating the
|
|
Shinya Kitaoka |
120a6e |
// sums.
|
|
Shinya Kitaoka |
120a6e |
for (x = 0; xNew != lx; ++x, ++xNew, lineIn += addIn, newPixIn += addIn,
|
|
Shinya Kitaoka |
120a6e |
pixsum += addSum, pixcount += addSum) {
|
|
Shinya Kitaoka |
120a6e |
const pixIn_type &npi = *newPixIn, &li = *lineIn;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (selector(npi)) sum = sum + npi, ++count;
|
|
Shinya Kitaoka |
120a6e |
if (selector(li)) sum = sum - li, --count;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
*pixsum = *pixsum + sum, *pixcount += count;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Finally, without adding new pixels
|
|
Shinya Kitaoka |
120a6e |
for (; x != lx;
|
|
Shinya Kitaoka |
120a6e |
++x, lineIn += addIn, pixsum += addSum, pixcount += addSum) {
|
|
Shinya Kitaoka |
120a6e |
const pixIn_type &li = *lineIn;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (selector(li)) sum = sum - li, --count;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
*pixsum = *pixsum + sum, *pixcount += count;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
memset(sums, 0, lx * sizeof(PixSum));
|
|
Shinya Kitaoka |
120a6e |
memset(counts, 0, lx * sizeof(int));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Add *strict* halves of the convolution sums
|
|
Shinya Kitaoka |
120a6e |
locals::fillSums(lx, radius, in, sums, counts, addIn, 1, selector);
|
|
Shinya Kitaoka |
120a6e |
locals::fillSums(lx, radius, in + addIn * (lx - 1), sums + lx - 1,
|
|
Shinya Kitaoka |
120a6e |
counts + lx - 1, -addIn, -1, selector);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Normalize sums
|
|
Shinya Kitaoka |
120a6e |
for (int x = 0; x != lx; ++x, in += addIn, out += addOut, ++sums, ++counts) {
|
|
Shinya Kitaoka |
120a6e |
using namespace pixel_ops;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(*counts >= 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
pixIn_type pix(*in);
|
|
Shinya Kitaoka |
120a6e |
pixel_ops::assign(pix, (*sums + pix) / (*counts + 1));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
*out = pix;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename imgin,="" imgout,="" scalar="" typename=""></typename>
|
|
Shinya Kitaoka |
120a6e |
void blurRows(const ImgIn &imgIn, ImgOut &imgOut, int radius, Scalar) {
|
|
Shinya Kitaoka |
120a6e |
typedef typename image_traits<imgin>::pixel_ptr_type PtrIn;</imgin>
|
|
Shinya Kitaoka |
120a6e |
typedef typename image_traits<imgout>::pixel_ptr_type PtrOut;</imgout>
|
|
Shinya Kitaoka |
120a6e |
typedef tcg::Pixel<scalar, image_traits<imgin="">::pixel_category> PixSum;</scalar,>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Validate parameters
|
|
Shinya Kitaoka |
120a6e |
int inLx = image_traits<imgin>::width(imgIn),</imgin>
|
|
Shinya Kitaoka |
120a6e |
inLy = image_traits<imgin>::height(imgIn);</imgin>
|
|
Shinya Kitaoka |
120a6e |
int outLx = image_traits<imgout>::width(imgOut),</imgout>
|
|
Shinya Kitaoka |
120a6e |
outLy = image_traits<imgout>::height(imgOut);</imgout>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(inLx == outLx && inLy == outLy);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int inWrap = image_traits<imgin>::wrap(imgIn),</imgin>
|
|
Shinya Kitaoka |
120a6e |
outWrap = image_traits<imgout>::wrap(imgOut);</imgout>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Allocate an intermediate line of pixels to store sum values
|
|
Shinya Kitaoka |
120a6e |
tcg::unique_ptr<pixsum[]> sums(new PixSum[inLx]);</pixsum[]>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Filter rows
|
|
Shinya Kitaoka |
120a6e |
for (int y = 0; y != inLy; ++y) {
|
|
Shinya Kitaoka |
120a6e |
PtrIn lineIn = image_traits<imgin>::pixel(imgIn, 0, y);</imgin>
|
|
Shinya Kitaoka |
120a6e |
PtrOut lineOut = image_traits<imgout>::pixel(imgOut, 0, y);</imgout>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
_flatFilterLine(lineIn, lineOut, inLx, 1, 1, radius, sums.get());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
template
|
|
Shinya Kitaoka |
120a6e |
typename Scalar>
|
|
Shinya Kitaoka |
120a6e |
void blurRows(const ImgIn &imgIn, ImgOut &imgOut, int radius,
|
|
Shinya Kitaoka |
120a6e |
SelectorFunc selector, Scalar) {
|
|
Shinya Kitaoka |
120a6e |
typedef typename image_traits<imgin>::pixel_ptr_type PtrIn;</imgin>
|
|
Shinya Kitaoka |
120a6e |
typedef typename image_traits<imgout>::pixel_ptr_type PtrOut;</imgout>
|
|
Shinya Kitaoka |
120a6e |
typedef tcg::Pixel<scalar, image_traits<imgin="">::pixel_category> PixSum;</scalar,>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Validate parameters
|
|
Shinya Kitaoka |
120a6e |
int inLx = image_traits<imgin>::width(imgIn),</imgin>
|
|
Shinya Kitaoka |
120a6e |
inLy = image_traits<imgin>::height(imgIn);</imgin>
|
|
Shinya Kitaoka |
120a6e |
int outLx = image_traits<imgout>::width(imgOut),</imgout>
|
|
Shinya Kitaoka |
120a6e |
outLy = image_traits<imgout>::height(imgOut);</imgout>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(inLx == outLx && inLy == outLy);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int inWrap = image_traits<imgin>::wrap(imgIn),</imgin>
|
|
Shinya Kitaoka |
120a6e |
outWrap = image_traits<imgout>::wrap(imgOut);</imgout>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Allocate an intermediate line of pixels to store sum values
|
|
Shinya Kitaoka |
120a6e |
tcg::unique_ptr<pixsum[]> sums(new PixSum[inLx]);</pixsum[]>
|
|
Shinya Kitaoka |
120a6e |
tcg::unique_ptr<int[]> counts(new int[inLx]);</int[]>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Filter rows
|
|
Shinya Kitaoka |
120a6e |
for (int y = 0; y != inLy; ++y) {
|
|
Shinya Kitaoka |
120a6e |
PtrIn lineIn = image_traits<imgin>::pixel(imgIn, 0, y);</imgin>
|
|
Shinya Kitaoka |
120a6e |
PtrOut lineOut = image_traits<imgout>::pixel(imgOut, 0, y);</imgout>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
_flatFilterLine(lineIn, lineOut, inLx, 1, 1, selector, radius, sums.get(),
|
|
Shinya Kitaoka |
120a6e |
counts.get());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename imgin,="" imgout,="" scalar="" typename=""></typename>
|
|
Shinya Kitaoka |
120a6e |
void blurCols(const ImgIn &imgIn, ImgOut &imgOut, int radius, Scalar) {
|
|
Shinya Kitaoka |
120a6e |
typedef typename image_traits<imgin>::pixel_ptr_type PtrIn;</imgin>
|
|
Shinya Kitaoka |
120a6e |
typedef typename image_traits<imgout>::pixel_ptr_type PtrOut;</imgout>
|
|
Shinya Kitaoka |
120a6e |
typedef tcg::Pixel<scalar, image_traits<imgin="" typename="">::pixel_category></scalar,>
|
|
Shinya Kitaoka |
120a6e |
PixSum;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Validate parameters
|
|
Shinya Kitaoka |
120a6e |
int inLx = image_traits<imgin>::width(imgIn),</imgin>
|
|
Shinya Kitaoka |
120a6e |
inLy = image_traits<imgin>::height(imgIn);</imgin>
|
|
Shinya Kitaoka |
120a6e |
int outLx = image_traits<imgout>::width(imgOut),</imgout>
|
|
Shinya Kitaoka |
120a6e |
outLy = image_traits<imgout>::height(imgOut);</imgout>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(inLx == outLx && inLy == outLy);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int inWrap = image_traits<imgin>::wrap(imgIn),</imgin>
|
|
Shinya Kitaoka |
120a6e |
outWrap = image_traits<imgout>::wrap(imgOut);</imgout>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Allocate an intermediate line of pixels to store sum values
|
|
Shinya Kitaoka |
120a6e |
tcg::unique_ptr<pixsum[]> sums(new PixSum[inLy]);</pixsum[]>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Filter columns
|
|
Shinya Kitaoka |
120a6e |
for (int x = 0; x != inLx; ++x) {
|
|
Shinya Kitaoka |
120a6e |
PtrIn lineIn = image_traits<imgin>::pixel(imgIn, x, 0);</imgin>
|
|
Shinya Kitaoka |
120a6e |
PtrOut lineOut = image_traits<imgout>::pixel(imgOut, x, 0);</imgout>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
_flatFilterLine(lineIn, lineOut, inLy, inWrap, outWrap, radius, sums.get());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
template
|
|
Shinya Kitaoka |
120a6e |
typename Scalar>
|
|
Shinya Kitaoka |
120a6e |
void blurCols(const ImgIn &imgIn, ImgOut &imgOut, int radius,
|
|
Shinya Kitaoka |
120a6e |
SelectorFunc selector, Scalar) {
|
|
Shinya Kitaoka |
120a6e |
typedef typename image_traits<imgin>::pixel_ptr_type PtrIn;</imgin>
|
|
Shinya Kitaoka |
120a6e |
typedef typename image_traits<imgout>::pixel_ptr_type PtrOut;</imgout>
|
|
Shinya Kitaoka |
120a6e |
typedef tcg::Pixel<scalar, image_traits<imgin="" typename="">::pixel_category></scalar,>
|
|
Shinya Kitaoka |
120a6e |
PixSum;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Validate parameters
|
|
Shinya Kitaoka |
120a6e |
int inLx = image_traits<imgin>::width(imgIn),</imgin>
|
|
Shinya Kitaoka |
120a6e |
inLy = image_traits<imgin>::height(imgIn);</imgin>
|
|
Shinya Kitaoka |
120a6e |
int outLx = image_traits<imgout>::width(imgOut),</imgout>
|
|
Shinya Kitaoka |
120a6e |
outLy = image_traits<imgout>::height(imgOut);</imgout>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(inLx == outLx && inLy == outLy);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int inWrap = image_traits<imgin>::wrap(imgIn),</imgin>
|
|
Shinya Kitaoka |
120a6e |
outWrap = image_traits<imgout>::wrap(imgOut);</imgout>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Allocate an intermediate line of pixels to store sum values
|
|
Shinya Kitaoka |
120a6e |
tcg::unique_ptr<pixsum[]> sums(new PixSum[inLy]);</pixsum[]>
|
|
Shinya Kitaoka |
120a6e |
tcg::unique_ptr<int[]> counts(new int[inLy]);</int[]>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Filter columns
|
|
Shinya Kitaoka |
120a6e |
for (int x = 0; x != inLx; ++x) {
|
|
Shinya Kitaoka |
120a6e |
PtrIn lineIn = image_traits<imgin>::pixel(imgIn, x, 0);</imgin>
|
|
Shinya Kitaoka |
120a6e |
PtrOut lineOut = image_traits<imgout>::pixel(imgOut, x, 0);</imgout>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
_flatFilterLine(lineIn, lineOut, inLy, inWrap, outWrap, selector, radius,
|
|
Shinya Kitaoka |
120a6e |
sums.get(), counts.get());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename imgin,="" imgout,="" scalar="" typename=""></typename>
|
|
Shinya Kitaoka |
120a6e |
void blur(const ImgIn &imgIn, ImgOut &imgOut, int radius, Scalar) {
|
|
Shinya Kitaoka |
120a6e |
blurRows(imgIn, imgOut, radius, Scalar);
|
|
Shinya Kitaoka |
120a6e |
blurCols(imgOut, imgOut, radius, Scalar);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
template
|
|
Shinya Kitaoka |
120a6e |
typename Scalar>
|
|
Shinya Kitaoka |
120a6e |
void blur(const ImgIn &imgIn, ImgOut &imgOut, int radius, SelectorFunc selector,
|
|
Shinya Kitaoka |
120a6e |
Scalar) {
|
|
Shinya Kitaoka |
120a6e |
blurRows(imgIn, imgOut, radius, selector, Scalar);
|
|
Shinya Kitaoka |
120a6e |
blurCols(imgOut, imgOut, radius, selector, Scalar);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
} // namespace tcg::image_ops
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
#endif // TCG_IMAGE_OPS_HPP
|