【화상 처리 100개 노크에 도전】Q.12. 모션 필터
사용한 라이브러리
【화상 처리 100개 노크】 독자적인 화상 입출력 클래스를 만든다
Q.12. 모션 필터
모션 필터(3x3)를 구현하라.
모션 필터는 대각선 방향의 평균값을 취하는 필터이며, 다음 식으로 정의된다.
1/3 0 0
0 1/3 0
0 0 1/3
이것도 커널을 바꾸는 것뿐입니다. 간단한 흔들림의 모델에 해당합니다.
int main()
{
PPM ppm("imori.pnm");
int width = ppm.Get_width();
int height = ppm.Get_height();
PPM ppm2(width, height);
auto kernel = [&](int i, int j)
{
double ret = 0;
if (i == 0 && j == 0) ret = 1;
else if (i * j == 1) ret = 1;
return ret;
};
auto conv = [&](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++)
{
int sum = 0;
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)
{
ret[i][j] += kernel(di, dj) * f[i - di][j - dj];
sum += kernel(di, dj);
}
}
ret[i][j] /= (double)sum;
}
return ret;
};
std::vector < std::vector < double >> arrr(width, std::vector<double>(height));
std::vector < std::vector < double >> arrg(width, std::vector<double>(height));
std::vector < std::vector < double >> arrb(width, std::vector<double>(height));
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
arrr[i][j] = ppm(i, j, 'r');
arrg[i][j] = ppm(i, j, 'g');
arrb[i][j] = ppm(i, j, 'b');
}
arrr = conv(arrr);
arrg = conv(arrg);
arrb = conv(arrb);
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
ppm2(i, j, 'r') = arrr[i][j];
ppm2(i, j, 'g') = arrg[i][j];
ppm2(i, j, 'b') = arrb[i][j];
}
ppm2.Flush("out.ppm");
return 0;
}
Reference
이 문제에 관하여(【화상 처리 100개 노크에 도전】Q.12. 모션 필터), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/jajagacchi/items/7ca2b0ed4815900ac610
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
모션 필터(3x3)를 구현하라.
모션 필터는 대각선 방향의 평균값을 취하는 필터이며, 다음 식으로 정의된다.
1/3 0 0
0 1/3 0
0 0 1/3
이것도 커널을 바꾸는 것뿐입니다. 간단한 흔들림의 모델에 해당합니다.
int main()
{
PPM ppm("imori.pnm");
int width = ppm.Get_width();
int height = ppm.Get_height();
PPM ppm2(width, height);
auto kernel = [&](int i, int j)
{
double ret = 0;
if (i == 0 && j == 0) ret = 1;
else if (i * j == 1) ret = 1;
return ret;
};
auto conv = [&](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++)
{
int sum = 0;
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)
{
ret[i][j] += kernel(di, dj) * f[i - di][j - dj];
sum += kernel(di, dj);
}
}
ret[i][j] /= (double)sum;
}
return ret;
};
std::vector < std::vector < double >> arrr(width, std::vector<double>(height));
std::vector < std::vector < double >> arrg(width, std::vector<double>(height));
std::vector < std::vector < double >> arrb(width, std::vector<double>(height));
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
arrr[i][j] = ppm(i, j, 'r');
arrg[i][j] = ppm(i, j, 'g');
arrb[i][j] = ppm(i, j, 'b');
}
arrr = conv(arrr);
arrg = conv(arrg);
arrb = conv(arrb);
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
ppm2(i, j, 'r') = arrr[i][j];
ppm2(i, j, 'g') = arrg[i][j];
ppm2(i, j, 'b') = arrb[i][j];
}
ppm2.Flush("out.ppm");
return 0;
}
Reference
이 문제에 관하여(【화상 처리 100개 노크에 도전】Q.12. 모션 필터), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/jajagacchi/items/7ca2b0ed4815900ac610텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)