【이미지 처리 100개 노크에 도전】Q.17. Laplacian 필터
사용한 라이브러리
【화상 처리 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;
}
Reference
이 문제에 관하여(【이미지 처리 100개 노크에 도전】Q.17. Laplacian 필터), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/jajagacchi/items/427bf2cea7f1b0475804
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
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;
}
Reference
이 문제에 관하여(【이미지 처리 100개 노크에 도전】Q.17. Laplacian 필터), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/jajagacchi/items/427bf2cea7f1b0475804텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)