【이미지 처리 100개 노크에 도전】Q.17. Laplacian 필터

15165 단어 C++이미지 처리

사용한 라이브러리



【화상 처리 100개 노크】 독자적인 화상 입출력 클래스를 만든다

Q.17. Laplacian 필터



Laplacian 필터를 구현하십시오.
Laplacian(라플라시안) 필터는 휘도의 2차 미분을 취함으로써 엣지 검출을 행하는 필터이다.

라플라시안 필터는 사용한 적이 없습니다. 라플라시안의 차분 근사 자체는 계산한 적이 있으므로 생략합니다. 이것도 커널을 바꾸는 것뿐입니다. 여기 편은 필터 지옥이군요. 빨리 빠져나가고 싶다···.
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 = -4;
        if (i * j == 0 && (abs(i) == 1 || abs(j) == 1)) ret = 1;
        return ret;// / 16.;
    };

    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 >> 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 = conv(arry);

    for (int j = 0; j < height; j++)
        for (int i = 0; i < width; i++)
        {
            int val = abs(arry[i][j]);
            if (val > 255) val = 255;
            ppm2(i, j, 'r') = val;
            ppm2(i, j, 'g') = val;
            ppm2(i, j, 'b') = val;

        }

    ppm2.Flush("out.ppm");
    return 0;
}

좋은 웹페이지 즐겨찾기