【화상 처리 100개 노크에 도전】Q.32. 푸리에 변환
사용한 라이브러리
【화상 처리 100개 노크】 독자적인 화상 입출력 클래스를 만든다
【화상 처리 100개 노크에 도전】독자적인 이산 푸리에 변환 클래스를 만든다
Q.32. 푸리에 변환
2차원 이산 푸리에 변환(DFT)을 구현하고 imori.jpg를 그레이스케일화했지만 주파수의 파워 스펙트럼을 표시하라. 또한 역이차원 이산 푸리에 변환(IDFT)으로 이미지를 복원하라.
이미지의 파워 스펙트럼은 직류 부근의 값이 크기 때문에 원점 부근만 새하얗게 되어 전체 분포를 잘 모르는 경우가 많습니다. 이 때문에 종종 로그가 표시됩니다. 이번에는 수치 데이터로 출력하여 Gnuplot으로 log 표시합니다.
int main()
{
PPM ppm("imori.pnm");
int width = ppm.Get_width();
int height = ppm.Get_height();
std::vector<std::vector<std::complex<double>>> f(width, std::vector<std::complex<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);
f[i][j] = y;
}
DFT2D dft2d(width, height);
auto F = dft2d.forward(f);
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
std::cout << i << " " << j << " " << std::abs(F[i][j]) << std::endl;
}
std::cout << std::endl;
}
f = dft2d.backward(F);
PPM ppm2(width, height);
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
int val = f[i][j].real();
if (val >= 256) val = 255;
if (val < 0)val = 0;
ppm2(i, j, 'r') = val;
ppm2(i, j, 'g') = val;
ppm2(i, j, 'b') = val;
}
ppm2.Flush("out.ppm");
return 0;
}
gnuplot> set log z
gnuplot> splot "fourier.txt" using 1:2:3 with pm3d
미묘···.
Reference
이 문제에 관하여(【화상 처리 100개 노크에 도전】Q.32. 푸리에 변환), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/jajagacchi/items/0c87942b7c7a5658099a
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
2차원 이산 푸리에 변환(DFT)을 구현하고 imori.jpg를 그레이스케일화했지만 주파수의 파워 스펙트럼을 표시하라. 또한 역이차원 이산 푸리에 변환(IDFT)으로 이미지를 복원하라.
이미지의 파워 스펙트럼은 직류 부근의 값이 크기 때문에 원점 부근만 새하얗게 되어 전체 분포를 잘 모르는 경우가 많습니다. 이 때문에 종종 로그가 표시됩니다. 이번에는 수치 데이터로 출력하여 Gnuplot으로 log 표시합니다.
int main()
{
PPM ppm("imori.pnm");
int width = ppm.Get_width();
int height = ppm.Get_height();
std::vector<std::vector<std::complex<double>>> f(width, std::vector<std::complex<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);
f[i][j] = y;
}
DFT2D dft2d(width, height);
auto F = dft2d.forward(f);
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
std::cout << i << " " << j << " " << std::abs(F[i][j]) << std::endl;
}
std::cout << std::endl;
}
f = dft2d.backward(F);
PPM ppm2(width, height);
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
int val = f[i][j].real();
if (val >= 256) val = 255;
if (val < 0)val = 0;
ppm2(i, j, 'r') = val;
ppm2(i, j, 'g') = val;
ppm2(i, j, 'b') = val;
}
ppm2.Flush("out.ppm");
return 0;
}
gnuplot> set log z
gnuplot> splot "fourier.txt" using 1:2:3 with pm3d
미묘···.
Reference
이 문제에 관하여(【화상 처리 100개 노크에 도전】Q.32. 푸리에 변환), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/jajagacchi/items/0c87942b7c7a5658099a텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)