使用したライブラリ
Q.13. MAX-MINフィルタ
MAX-MINフィルタ(3x3)を実装せよ。
MAX-MINフィルタとはフィルタ内の画素の最大値と最小値の差を出力するフィルタであり、エッジ検出のフィルタの一つである。 エッジ検出とは画像内の線を検出るすることであり、このような画像内の情報を抜き出す操作を特徴抽出と呼ぶ。 エッジ検出では多くの場合、グレースケール画像に対してフィルタリングを行う。
こういうフィルタがあることを初めて知りました。差を取るので微分フィルタっぽい動きをするのでしょう。やはりエッジ検出に使われるようです。微分フィルタと比べるとどうなんだろう?
Q.10のメディアンフィルタを少し改造すればOK。
int main()
{
PPM ppm("imori.pnm");
int width = ppm.Get_width();
int height = ppm.Get_height();
PPM ppm2(width, height);
auto max_min = [&](const std::vector<std::vector<double>>& f)
{
std::vector < std::vector < double >> ret(width, std::vector<double>(height));
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
ret[i][j] = 0;
}
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
std::vector<int> list;
for (int di = -1; di <= 1; di++)
for (int dj = -1; dj <= 1; dj++)
{
if (i - di >= 0 && i - di < width && j - dj >= 0 && j - di < height)
{
list.push_back(f[i - di][j - dj]);
}
else
{
list.push_back(0);
}
}
std::sort(list.begin(), list.end());
ret[i][j] = (list[8]-list[0]);
}
return ret;
};
std::vector < std::vector < double >> arry(width, std::vector<double>(height));
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
int r = ppm(i, j, 'r');
int g = ppm(i, j, 'g');
int b = ppm(i, j, 'b');
int y = (std::round)(0.2126 * r + 0.7152 * g + 0.0722 * b);
arry[i][j] = y;
}
arry = max_min(arry);
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
ppm2(i, j, 'r') = arry[i][j];
ppm2(i, j, 'g') = arry[i][j];
ppm2(i, j, 'b') = arry[i][j];
}
ppm2.Flush("out.ppm");
return 0;
}