【화상 처리 100개 노크에 도전】Q.10 메디안 필터
사용한 라이브러리
【화상 처리 100개 노크】 독자적인 화상 입출력 클래스를 만든다
Q.10 메디안 필터
메디안 필터(3x3)를 구현하여 imori_noise.jpg의 노이즈를 제거하라.
Q.9의 가우시안 필터를 조금 개조하면 간단합니다. 평소에는 가우시안 필터를 사용하는 것보다 메디안 필터를 사용하는 것이 많습니다.
int main()
{
PPM ppm("imori_noise.pnm");
int width = ppm.Get_width();
int height = ppm.Get_height();
PPM ppm2(width, height);
auto median = [&](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[4];
}
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 = median(arrr);
arrg = median(arrg);
arrb = median(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.10 메디안 필터), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/jajagacchi/items/abe594d1d80e2afbecac
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
메디안 필터(3x3)를 구현하여 imori_noise.jpg의 노이즈를 제거하라.
Q.9의 가우시안 필터를 조금 개조하면 간단합니다. 평소에는 가우시안 필터를 사용하는 것보다 메디안 필터를 사용하는 것이 많습니다.
int main()
{
PPM ppm("imori_noise.pnm");
int width = ppm.Get_width();
int height = ppm.Get_height();
PPM ppm2(width, height);
auto median = [&](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[4];
}
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 = median(arrr);
arrg = median(arrg);
arrb = median(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.10 메디안 필터), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/jajagacchi/items/abe594d1d80e2afbecac텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)