|
Toshihiro Shimizu |
890ddd |
#include <cmath> /* sqrt() */</cmath>
|
|
Toshihiro Shimizu |
890ddd |
#include <vector></vector>
|
|
Toshihiro Shimizu |
890ddd |
#include "igs_ifx_common.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
/* 画像の外への参照が必要なときどう拾うか */
|
|
Toshihiro Shimizu |
890ddd |
enum outside_of_image_ {
|
|
Shinya Kitaoka |
120a6e |
is_spread_edge_ /* 今はここしか使ってない2013-11-12 */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
is_flip_repeat_,
|
|
Shinya Kitaoka |
120a6e |
is_black_,
|
|
Shinya Kitaoka |
120a6e |
is_repeat_
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
/* 影響範囲(radius)の各ピクセルのgeometry情報 */
|
|
Shinya Kitaoka |
120a6e |
class pixel_geometry_ {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
pixel_geometry_(const double radius, const outside_of_image_ type)
|
|
Shinya Kitaoka |
120a6e |
: type_(type), ratio_total(0.0) {
|
|
Shinya Kitaoka |
120a6e |
/* 辿るためピクセル整数位置 */
|
|
Shinya Kitaoka |
120a6e |
const int radius_int = static_cast<int>(ceil(radius));</int>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/* 任意半径(double値)の中のピクセル数を数える */
|
|
Shinya Kitaoka |
120a6e |
const double rxr = radius * radius + 1e-6;
|
|
Shinya Kitaoka |
120a6e |
for (int yy = -radius_int; yy <= radius_int; ++yy) {
|
|
Shinya Kitaoka |
120a6e |
const double yxy = static_cast<double>(yy) * yy;</double>
|
|
Shinya Kitaoka |
120a6e |
for (int xx = -radius_int; xx <= radius_int; ++xx) {
|
|
Shinya Kitaoka |
120a6e |
const double xxx_plus_yxy = static_cast<double>(xx) * xx + yxy;</double>
|
|
Shinya Kitaoka |
120a6e |
if (xxx_plus_yxy <= rxr) { /* 円の内部なら */
|
|
Shinya Kitaoka |
120a6e |
/* 円の中心位置を原点(0,0)とした座標 */
|
|
Shinya Kitaoka |
120a6e |
this->xp.push_back(xx);
|
|
Shinya Kitaoka |
120a6e |
this->yp.push_back(yy);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/* 中心からpixelまでの距離(半径) */
|
|
Shinya Kitaoka |
120a6e |
const double pixel_radius = sqrt(xxx_plus_yxy);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/* 影響力を現す値
|
|
Shinya Kitaoka |
120a6e |
円縁から0...1の距離ならそのまま、
|
|
Shinya Kitaoka |
120a6e |
1以上離れて中心までは1とする */
|
|
Shinya Kitaoka |
120a6e |
double ratio = radius - pixel_radius;
|
|
Shinya Kitaoka |
120a6e |
if (1.0 < ratio) {
|
|
Shinya Kitaoka |
120a6e |
ratio = 1.0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
this->in_out_ratio.push_back(ratio);
|
|
Shinya Kitaoka |
120a6e |
this->ratio_total += ratio;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
void re_position(const int ww, const int hh, int &xx, int &yy) {
|
|
Shinya Kitaoka |
120a6e |
switch (this->type_) {
|
|
Shinya Kitaoka |
120a6e |
case is_spread_edge_: /* 外枠のピクセル値を広げる */
|
|
Shinya Kitaoka |
120a6e |
xx = (xx < 0) ? 0 : ((ww <= xx) ? ww - 1 : xx);
|
|
Shinya Kitaoka |
120a6e |
yy = (yy < 0) ? 0 : ((hh <= yy) ? hh - 1 : yy);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case is_flip_repeat_: /* 同じ絵を上下左右に反転繰り返す */
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
int ii = 0;
|
|
Shinya Kitaoka |
120a6e |
while (xx < 0) {
|
|
Shinya Kitaoka |
120a6e |
xx += ww;
|
|
Shinya Kitaoka |
120a6e |
++ii;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if ((ii % 2) == 1) {
|
|
Shinya Kitaoka |
120a6e |
xx = ww - 1 - xx;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
int ii = 0;
|
|
Shinya Kitaoka |
120a6e |
while (ww <= xx) {
|
|
Shinya Kitaoka |
120a6e |
xx -= ww;
|
|
Shinya Kitaoka |
120a6e |
++ii;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if ((ii % 2) == 1) {
|
|
Shinya Kitaoka |
120a6e |
xx = ww - 1 - xx;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
int ii = 0;
|
|
Shinya Kitaoka |
120a6e |
while (yy < 0) {
|
|
Shinya Kitaoka |
120a6e |
yy += hh;
|
|
Shinya Kitaoka |
120a6e |
++ii;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if ((ii % 2) == 1) {
|
|
Shinya Kitaoka |
120a6e |
yy = hh - 1 - yy;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
int ii = 0;
|
|
Shinya Kitaoka |
120a6e |
while (hh <= yy) {
|
|
Shinya Kitaoka |
120a6e |
yy -= hh;
|
|
Shinya Kitaoka |
120a6e |
++ii;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if ((ii % 2) == 1) {
|
|
Shinya Kitaoka |
120a6e |
yy = hh - 1 - yy;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case is_black_: /* -1として外関数で黒塗り処理する */
|
|
Shinya Kitaoka |
120a6e |
if (xx < 0 || ww <= xx) {
|
|
Shinya Kitaoka |
120a6e |
xx = -1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (yy < 0 || hh <= yy) {
|
|
Shinya Kitaoka |
120a6e |
yy = -1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case is_repeat_: /* 同じ絵を上下左右繰り返す */
|
|
Shinya Kitaoka |
120a6e |
while (xx < 0) {
|
|
Shinya Kitaoka |
120a6e |
xx += ww;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
while (ww <= xx) {
|
|
Shinya Kitaoka |
120a6e |
xx -= ww;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
while (yy < 0) {
|
|
Shinya Kitaoka |
120a6e |
yy += hh;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
while (hh <= yy) {
|
|
Shinya Kitaoka |
120a6e |
yy -= hh;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
void clear(void) {
|
|
Shinya Kitaoka |
120a6e |
this->yp.clear();
|
|
Shinya Kitaoka |
120a6e |
this->xp.clear();
|
|
Shinya Kitaoka |
120a6e |
this->in_out_ratio.clear();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> xp;</int>
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> yp;</int>
|
|
Shinya Kitaoka |
120a6e |
std::vector<double> in_out_ratio;</double>
|
|
Shinya Kitaoka |
120a6e |
double ratio_total;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
pixel_geometry_();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
outside_of_image_ type_;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
/* 指定位置のピクセルの値 */
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
T get_pixel_value_(pixel_geometry_ &pixg, const T *image_top, const int hh,
|
|
Shinya Kitaoka |
120a6e |
const int ww, const int ch, int xx, int yy, const int zz) {
|
|
Shinya Kitaoka |
120a6e |
pixg.re_position(ww, hh, xx, yy);
|
|
Shinya Kitaoka |
120a6e |
if ((xx < 0) || (yy < 0)) {
|
|
Shinya Kitaoka |
120a6e |
return 0; /* 黒 */
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return *(image_top + (ww * ch * yy + ch * xx + zz));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
// #include <algorithm> // std::sort()</algorithm>
|
|
Toshihiro Shimizu |
890ddd |
#include <stdexcept> /* std::domain_error(-) */</stdexcept>
|
|
Shinya Kitaoka |
120a6e |
#include <limits> /* std::numeric_limits */</limits>
|
|
Shinya Kitaoka |
120a6e |
#include <map> /* std::multimap */</map>
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Shinya Kitaoka |
120a6e |
Median Filter...
|
|
Shinya Kitaoka |
120a6e |
+---+---+---+ +---+---+---+
|
|
Shinya Kitaoka |
120a6e |
| 5 | 6 | 7 | | 5 | 6 | 7 |
|
|
Shinya Kitaoka |
120a6e |
+---+---+---+ +---+---+---+
|
|
Shinya Kitaoka |
120a6e |
| 4 | 9 | 6 | --> 3,4,4,5,5,6,6,7,9 --> | 4 | 5 | 6 |
|
|
Shinya Kitaoka |
120a6e |
+---+---+---+ ^ +---+---+---+
|
|
Shinya Kitaoka |
120a6e |
| 3 | 4 | 5 | | | 3 | 4 | 5 |
|
|
Shinya Kitaoka |
120a6e |
+---+---+---+ median +---+---+---+
|
|
Shinya Kitaoka |
120a6e |
--> ...Smoothing...
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
double median_filter_smooth_(pixel_geometry_ &pixg, const T *image_top,
|
|
Shinya Kitaoka |
120a6e |
const int hh, const int ww, const int ch,
|
|
Shinya Kitaoka |
120a6e |
const int xx, const int yy, const int zz) {
|
|
Shinya Kitaoka |
120a6e |
/* ピクセル値と影響値のペアにして、ソートしたリストを作成 */
|
|
Shinya Kitaoka |
120a6e |
std::multimap<double, double=""> pixels;</double,>
|
|
Shinya Kitaoka |
120a6e |
for (unsigned int ii = 0; ii < pixg.xp.size(); ++ii) {
|
|
Shinya Kitaoka |
120a6e |
const double value = static_cast<double>(</double>
|
|
Shinya Kitaoka |
120a6e |
get_pixel_value_(pixg, image_top, hh, ww, ch, xx + pixg.xp.at(ii),
|
|
Shinya Kitaoka |
120a6e |
yy + pixg.yp.at(ii), zz));
|
|
Shinya Kitaoka |
120a6e |
pixels.insert(std::pair<double, double="">(value, pixg.in_out_ratio.at(ii)));</double,>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/* 取り出しやすいようにvectorに移し変える */
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
+---+---+---+---+---+
|
|
Shinya Kitaoka |
120a6e |
| 0 | 1 | 2 | 3 | 4 | <-- pixel value
|
|
Shinya Kitaoka |
120a6e |
+---+---+---+---+---+
|
|
Shinya Kitaoka |
120a6e |
^-^---^---^---^---^-^
|
|
Shinya Kitaoka |
120a6e |
0 1 2 3 4 5 <-- len_each
|
|
Shinya Kitaoka |
120a6e |
+>0-->1-->2-->3-->4>5 <-- len_accum
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
/* 中央(median)位置の前後ピクセル位置を得
|
|
Shinya Kitaoka |
120a6e |
中央値を求める */
|
|
Shinya Kitaoka |
120a6e |
double len_median = pixg.ratio_total / 2.0; /* 並べたときの中間位置 */
|
|
Shinya Kitaoka |
120a6e |
double accum = 0.0;
|
|
Shinya Kitaoka |
120a6e |
double before_value = 0.0;
|
|
Shinya Kitaoka |
120a6e |
double before_ratio = 0.0;
|
|
Shinya Kitaoka |
120a6e |
double before_accum = 0.0;
|
|
Shinya Kitaoka |
120a6e |
for (std::multimap<double, double="">::iterator it = pixels.begin();</double,>
|
|
Shinya Kitaoka |
120a6e |
it != pixels.end();
|
|
Shinya Kitaoka |
120a6e |
++it, before_value = (*it).first, before_ratio = (*it).second,
|
|
Shinya Kitaoka |
120a6e |
before_accum = accum) {
|
|
Shinya Kitaoka |
120a6e |
/* ピクセル間の距離 */
|
|
Shinya Kitaoka |
120a6e |
const double pixw = (*it).second / 2.0 + before_ratio / 2.0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/* 開始端からの(ピクセル単位の)距離 */
|
|
Shinya Kitaoka |
120a6e |
accum += pixw; /* Pixelの中央の位置 */
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (len_median <= accum) {
|
|
Shinya Kitaoka |
120a6e |
/* 開始端から始めのピクセルの半分位置までの間 */
|
|
Shinya Kitaoka |
120a6e |
if (it == pixels.begin()) {
|
|
Shinya Kitaoka |
120a6e |
return (*it).first;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (before_value < (*it).first) {
|
|
Shinya Kitaoka |
120a6e |
return ((*it).first - before_value) * (len_median - before_accum) /
|
|
Shinya Kitaoka |
120a6e |
pixw +
|
|
Shinya Kitaoka |
120a6e |
before_value;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return (before_value - (*it).first) * (accum - len_median) / pixw +
|
|
Shinya Kitaoka |
120a6e |
(*it).first;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return before_value;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Shinya Kitaoka |
120a6e |
double refchk_(const double src, const double tgt, const double refv) {
|
|
Shinya Kitaoka |
120a6e |
return ((src < tgt) ? (tgt - src) * refv + src
|
|
Shinya Kitaoka |
120a6e |
: (src - tgt) * (1.0 - refv) + tgt) +
|
|
Shinya Kitaoka |
120a6e |
0.999999;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
template <class class="" it,="" rt=""></class>
|
|
Toshihiro Shimizu |
890ddd |
void convert_each_to_all_channels_template_(
|
|
Shinya Kitaoka |
120a6e |
const IT *in, IT *out, const int hh, const int ww, const int ch
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const RT *ref /* 求める画像(out)と同じ高さ、幅、チャンネル数 */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int ref_mode // R,G,B,A,luminance
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int zz, const double radius, const outside_of_image_ type) {
|
|
Shinya Kitaoka |
120a6e |
pixel_geometry_ pixg(radius, type);
|
|
Shinya Kitaoka |
120a6e |
const IT *in_pix = in;
|
|
Shinya Kitaoka |
120a6e |
IT *out_pix = out;
|
|
Shinya Kitaoka |
120a6e |
const int r_max = std::numeric_limits<rt>::max();</rt>
|
|
Shinya Kitaoka |
120a6e |
for (int yy = 0; yy < hh; ++yy) {
|
|
Shinya Kitaoka |
120a6e |
for (int xx = 0; xx < ww; ++xx, in_pix += ch, out_pix += ch) {
|
|
Shinya Kitaoka |
120a6e |
double refv = 1.0;
|
|
Shinya Kitaoka |
120a6e |
if (ref != 0) {
|
|
Shinya Kitaoka |
120a6e |
refv *= igs::color::ref_value(ref, ch, r_max, ref_mode);
|
|
Shinya Kitaoka |
120a6e |
ref += ch;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
const double v1 = median_filter_smooth_(pixg, in, hh, ww, ch, xx, yy, zz);
|
|
Shinya Kitaoka |
120a6e |
const IT v2 = static_cast<it>(refchk_(in_pix[zz], v1, refv));</it>
|
|
Shinya Kitaoka |
120a6e |
for (int zz = 0; zz < ch; ++zz) {
|
|
Shinya Kitaoka |
120a6e |
out_pix[zz] = v2;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
pixg.clear();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
template <class class="" it,="" rt=""></class>
|
|
Toshihiro Shimizu |
890ddd |
void convert_each_to_each_channel_template_(
|
|
Shinya Kitaoka |
120a6e |
const IT *in, IT *out, const int hh, const int ww, const int ch
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const RT *ref /* 求める画像(out)と同じ高さ、幅、チャンネル数 */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int ref_mode // R,G,B,A,luminance
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const double radius, const outside_of_image_ type) {
|
|
Shinya Kitaoka |
120a6e |
pixel_geometry_ pixg(radius, type);
|
|
Shinya Kitaoka |
120a6e |
const IT *in_pix = in;
|
|
Shinya Kitaoka |
120a6e |
IT *out_pix = out;
|
|
Shinya Kitaoka |
120a6e |
const int r_max = std::numeric_limits<rt>::max();</rt>
|
|
Shinya Kitaoka |
120a6e |
for (int yy = 0; yy < hh; ++yy) {
|
|
Shinya Kitaoka |
120a6e |
for (int xx = 0; xx < ww; ++xx, in_pix += ch, out_pix += ch) {
|
|
Shinya Kitaoka |
120a6e |
double refv = 1.0;
|
|
Shinya Kitaoka |
120a6e |
if (ref != 0) {
|
|
Shinya Kitaoka |
120a6e |
refv *= igs::color::ref_value(ref, ch, r_max, ref_mode);
|
|
Shinya Kitaoka |
120a6e |
ref += ch;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
for (int zz = 0; zz < ch; ++zz) {
|
|
Shinya Kitaoka |
120a6e |
const double v1 =
|
|
Shinya Kitaoka |
120a6e |
median_filter_smooth_(pixg, in, hh, ww, ch, xx, yy, zz);
|
|
Shinya Kitaoka |
120a6e |
out_pix[zz] = static_cast<it>(refchk_(in_pix[zz], v1, refv));</it>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
pixg.clear();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
#include "igs_median_filter_smooth.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "igs_ifx_common.h" /* igs::image::rgba */
|
|
Toshihiro Shimizu |
890ddd |
void igs::median_filter_smooth::convert(
|
|
Shinya Kitaoka |
120a6e |
const unsigned char *in_image, unsigned char *out_image
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int height, const int width, const int channels, const int bits
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const unsigned char *ref /* 求める画像と同じ高、幅、ch数 */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int ref_bits /* refがゼロのときはここもゼロ */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int ref_mode /* 0=R,1=G,2=B,3=A,4=Luminance,5=Nothing */
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int zz // 0(R),1(G),2(B),3(A),4(EachCh)
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const double radius // 0...
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int out_side_type // 0(Spread),1(Flip),2(bk),3(Repeat)
|
|
Shinya Kitaoka |
120a6e |
) {
|
|
Shinya Kitaoka |
120a6e |
/*--- 指定(zz)から、実際に処理すべき色チャンネル(z2)を得る ---*/
|
|
Shinya Kitaoka |
120a6e |
int z2 = zz;
|
|
Shinya Kitaoka |
120a6e |
if (igs::image::rgba::siz == channels) {
|
|
Shinya Kitaoka |
120a6e |
switch (zz) {
|
|
Shinya Kitaoka |
120a6e |
case 0:
|
|
Shinya Kitaoka |
120a6e |
z2 = igs::image::rgba::red;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 1:
|
|
Shinya Kitaoka |
120a6e |
z2 = igs::image::rgba::gre;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 2:
|
|
Shinya Kitaoka |
120a6e |
z2 = igs::image::rgba::blu;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 3:
|
|
Shinya Kitaoka |
120a6e |
z2 = igs::image::rgba::alp;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
default:
|
|
Shinya Kitaoka |
120a6e |
z2 = igs::image::rgba::siz;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (igs::image::rgb::siz == channels) {
|
|
Shinya Kitaoka |
120a6e |
switch (zz) {
|
|
Shinya Kitaoka |
120a6e |
case 0:
|
|
Shinya Kitaoka |
120a6e |
z2 = igs::image::rgb::red;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 1:
|
|
Shinya Kitaoka |
120a6e |
z2 = igs::image::rgb::gre;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 2:
|
|
Shinya Kitaoka |
120a6e |
z2 = igs::image::rgb::blu;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
default:
|
|
Shinya Kitaoka |
120a6e |
z2 = igs::image::rgb::siz;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (1 == channels) {
|
|
Shinya Kitaoka |
120a6e |
;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
throw std::domain_error("Bad channels,Not rgba/rgb/grayscale");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/*--- 指定(out_side_type)から、実際の処理方法(type)を設定 ---*/
|
|
Shinya Kitaoka |
120a6e |
outside_of_image_ type = is_spread_edge_;
|
|
Shinya Kitaoka |
120a6e |
switch (out_side_type) {
|
|
Shinya Kitaoka |
120a6e |
case 0:
|
|
Shinya Kitaoka |
120a6e |
type = is_spread_edge_;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 1:
|
|
Shinya Kitaoka |
120a6e |
type = is_flip_repeat_;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 2:
|
|
Shinya Kitaoka |
120a6e |
type = is_black_;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 3:
|
|
Shinya Kitaoka |
120a6e |
type = is_repeat_;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/* 処理 */
|
|
Shinya Kitaoka |
120a6e |
if ((std::numeric_limits<unsigned char="">::digits == bits) &&</unsigned>
|
|
Shinya Kitaoka |
120a6e |
((std::numeric_limits<unsigned char="">::digits == ref_bits) ||</unsigned>
|
|
Shinya Kitaoka |
120a6e |
(0 == ref_bits))) {
|
|
Shinya Kitaoka |
120a6e |
if ((0 <= z2) && (z2 < channels)) {
|
|
Shinya Kitaoka |
120a6e |
convert_each_to_all_channels_template_(in_image, out_image, height, width,
|
|
Shinya Kitaoka |
120a6e |
channels, ref, ref_mode, z2,
|
|
Shinya Kitaoka |
120a6e |
radius, type);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
convert_each_to_each_channel_template_(in_image, out_image, height, width,
|
|
Shinya Kitaoka |
120a6e |
channels, ref, ref_mode, radius,
|
|
Shinya Kitaoka |
120a6e |
type);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if ((std::numeric_limits<unsigned short="">::digits == bits) &&</unsigned>
|
|
Shinya Kitaoka |
120a6e |
((std::numeric_limits<unsigned char="">::digits == ref_bits) ||</unsigned>
|
|
Shinya Kitaoka |
120a6e |
(0 == ref_bits))) {
|
|
Shinya Kitaoka |
120a6e |
if ((0 <= z2) && (z2 < channels)) {
|
|
Shinya Kitaoka |
120a6e |
convert_each_to_all_channels_template_(
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<const *="" short="" unsigned="">(in_image),</const>
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<unsigned *="" short="">(out_image), height, width,</unsigned>
|
|
Shinya Kitaoka |
120a6e |
channels, ref, ref_mode, z2, radius, type);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
convert_each_to_each_channel_template_(
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<const *="" short="" unsigned="">(in_image),</const>
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<unsigned *="" short="">(out_image), height, width,</unsigned>
|
|
Shinya Kitaoka |
120a6e |
channels, ref, ref_mode, radius, type);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if ((std::numeric_limits<unsigned short="">::digits == bits) &&</unsigned>
|
|
Shinya Kitaoka |
120a6e |
(std::numeric_limits<unsigned short="">::digits == ref_bits)) {</unsigned>
|
|
Shinya Kitaoka |
120a6e |
if ((0 <= z2) && (z2 < channels)) {
|
|
Shinya Kitaoka |
120a6e |
convert_each_to_all_channels_template_(
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<const *="" short="" unsigned="">(in_image),</const>
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<unsigned *="" short="">(out_image), height, width,</unsigned>
|
|
Shinya Kitaoka |
120a6e |
channels, reinterpret_cast<const *="" short="" unsigned="">(ref), ref_mode, z2,</const>
|
|
Shinya Kitaoka |
120a6e |
radius, type);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
convert_each_to_each_channel_template_(
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<const *="" short="" unsigned="">(in_image),</const>
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<unsigned *="" short="">(out_image), height, width,</unsigned>
|
|
Shinya Kitaoka |
120a6e |
channels, reinterpret_cast<const *="" short="" unsigned="">(ref), ref_mode,</const>
|
|
Shinya Kitaoka |
120a6e |
radius, type);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if ((std::numeric_limits<unsigned char="">::digits == bits) &&</unsigned>
|
|
Shinya Kitaoka |
120a6e |
(std::numeric_limits<unsigned short="">::digits == ref_bits)) {</unsigned>
|
|
Shinya Kitaoka |
120a6e |
if ((0 <= z2) && (z2 < channels)) {
|
|
Shinya Kitaoka |
120a6e |
convert_each_to_all_channels_template_(
|
|
Shinya Kitaoka |
120a6e |
in_image, out_image, height, width, channels,
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<const *="" short="" unsigned="">(ref), ref_mode, z2, radius,</const>
|
|
Shinya Kitaoka |
120a6e |
type);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
convert_each_to_each_channel_template_(
|
|
Shinya Kitaoka |
120a6e |
in_image, out_image, height, width, channels,
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<const *="" short="" unsigned="">(ref), ref_mode, radius,</const>
|
|
Shinya Kitaoka |
120a6e |
type);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
throw std::domain_error("Bad bits,Not uchar/ushort");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|