【화상 처리 100개 노크에 도전】Q.10 메디안 필터

14741 단어 C++이미지 처리

사용한 라이브러리



【화상 처리 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;
}


과연 메디안 필터, 이런 스파이크적인 노이즈에는 매우 유효합니다. 가장자리도 잘 저장됩니다.

좋은 웹페이지 즐겨찾기