【화상 처리 100개 노크에 도전】Q.23. 히스토그램 평탄화
사용한 라이브러리
【화상 처리 100개 노크】 독자적인 화상 입출력 클래스를 만든다
Q.23. 히스토그램 평탄화
히스토그램 평탄화를 구현하라.
히스토그램 평탄화는 히스토그램을 평탄하게 변경하는 조작이며, 상기 평균값이나 표준 편차 등을 필요로하지 않고 히스토그램 값을 평형화하는 조작이다.
픽셀값 $z\to z'$의 변환은
z' = \frac{z_{\rm max}}{S} \sum_{i=0}^z h(i)
에서 주어진 것 같습니다. 뭐야 이 식.
식의 의미를 생각해 보자.
식을 조금 다시 작성해 봅니다. $\sum_{i=0}^z h(i)/S$는 누적 분포 함수이므로
\sum_{i=0}^z h(i)/S \equiv p(z)
로 정의합니다. 그러면 히스토그램 평탄화의 공식은
z' = z_{\rm max}p(z)
라고 쓸 수 있습니다. 누적 분포 함수로부터 접근하는 것이 전망이 좋을 것 같습니다.
목표는 히스토그램을 평탄화하는 것이 었습니다. 완전히 평평한 히스토그램의 경우 누적 분포 함수는 $z/z_{\rm max}$입니다. 그래서 $z$를 잘 변환하여 이상에 접근하는 것을 생각합니다.
여기서 이미지를 잡기 위해 $f(x)=x^2$의 선형화를 생각합니다. 이를 위해 $f(x)=X$ 되는 변수 $X$를 생각해 보자. 이러한 변수 변환을 하면 선형화가 가능합니다.
누적 분포 함수 $p(z)$ 의 이야기로 돌아갑니다. $p(z)$ 는 일반적으로 선형이 아니지만, 앞의 예를 따릅니다.
p(z) \equiv z'/z_{\rm max}
를 만족하는 변수 $z'$를 고려하십시오. 이것은 원래의 표현 자체입니다. 이산 변수이므로 엄밀한 평탄화는 일반적으로는 할 수 없지만, 그런데 어느 정도 효과가 있는지 살펴보겠습니다.
int main()
{
PPM ppm("imori.pnm");
int width = ppm.Get_width();
int height = ppm.Get_height();
int N = 256;
std::vector<int> hist(N);
std::vector<double> p(N);
for (int n = 0; n < N; n++)
{
hist[n] = 0;
p[n] = 0;
}
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
hist[ppm(i, j, 'r')]++;
hist[ppm(i, j, 'g')]++;
hist[ppm(i, j, 'b')]++;
}
for (int n = 0; n < N; n++)
for(int m=0; m<n+1; m++)
{
p[n] += hist[m]/(double)(3.*width*height);
}
std::ofstream ofs("p0.txt");
for (int n = 0; n < N; n++)
{
ofs << p[n] << std::endl;
}
int zmax = 255;
PPM ppm2(width, height);
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
ppm2(i, j, 'r') = zmax * p[ppm(i, j, 'r')];
ppm2(i, j, 'g') = zmax * p[ppm(i, j, 'g')];
ppm2(i, j, 'b') = zmax * p[ppm(i, j, 'b')];
}
for (int n = 0; n < N; n++)
{
hist[n] = 0;
p[n] = 0;
}
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
hist[ppm2(i, j, 'r')]++;
hist[ppm2(i, j, 'g')]++;
hist[ppm2(i, j, 'b')]++;
}
for (int n = 0; n < N; n++)
for (int m = 0; m < n + 1; m++)
{
p[n] += hist[m] / (double)(3. * width * height);
}
ppm2.Flush("out.ppm");
std::ofstream ofs2("p.txt");
for (int n = 0; n < N; n++)
{
ofs2 << p[n] << std::endl;
}
return 0;
}
누적 분포 함수는
오! 생각보다 평평하게!
Reference
이 문제에 관하여(【화상 처리 100개 노크에 도전】Q.23. 히스토그램 평탄화), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/jajagacchi/items/7e03c1e0356a07096797
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
히스토그램 평탄화를 구현하라.
히스토그램 평탄화는 히스토그램을 평탄하게 변경하는 조작이며, 상기 평균값이나 표준 편차 등을 필요로하지 않고 히스토그램 값을 평형화하는 조작이다.
픽셀값 $z\to z'$의 변환은
z' = \frac{z_{\rm max}}{S} \sum_{i=0}^z h(i)
에서 주어진 것 같습니다. 뭐야 이 식.
식의 의미를 생각해 보자.
식을 조금 다시 작성해 봅니다. $\sum_{i=0}^z h(i)/S$는 누적 분포 함수이므로
\sum_{i=0}^z h(i)/S \equiv p(z)
로 정의합니다. 그러면 히스토그램 평탄화의 공식은
z' = z_{\rm max}p(z)
라고 쓸 수 있습니다. 누적 분포 함수로부터 접근하는 것이 전망이 좋을 것 같습니다.
목표는 히스토그램을 평탄화하는 것이 었습니다. 완전히 평평한 히스토그램의 경우 누적 분포 함수는 $z/z_{\rm max}$입니다. 그래서 $z$를 잘 변환하여 이상에 접근하는 것을 생각합니다.
여기서 이미지를 잡기 위해 $f(x)=x^2$의 선형화를 생각합니다. 이를 위해 $f(x)=X$ 되는 변수 $X$를 생각해 보자. 이러한 변수 변환을 하면 선형화가 가능합니다.
누적 분포 함수 $p(z)$ 의 이야기로 돌아갑니다. $p(z)$ 는 일반적으로 선형이 아니지만, 앞의 예를 따릅니다.
p(z) \equiv z'/z_{\rm max}
를 만족하는 변수 $z'$를 고려하십시오. 이것은 원래의 표현 자체입니다. 이산 변수이므로 엄밀한 평탄화는 일반적으로는 할 수 없지만, 그런데 어느 정도 효과가 있는지 살펴보겠습니다.
int main()
{
PPM ppm("imori.pnm");
int width = ppm.Get_width();
int height = ppm.Get_height();
int N = 256;
std::vector<int> hist(N);
std::vector<double> p(N);
for (int n = 0; n < N; n++)
{
hist[n] = 0;
p[n] = 0;
}
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
hist[ppm(i, j, 'r')]++;
hist[ppm(i, j, 'g')]++;
hist[ppm(i, j, 'b')]++;
}
for (int n = 0; n < N; n++)
for(int m=0; m<n+1; m++)
{
p[n] += hist[m]/(double)(3.*width*height);
}
std::ofstream ofs("p0.txt");
for (int n = 0; n < N; n++)
{
ofs << p[n] << std::endl;
}
int zmax = 255;
PPM ppm2(width, height);
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
ppm2(i, j, 'r') = zmax * p[ppm(i, j, 'r')];
ppm2(i, j, 'g') = zmax * p[ppm(i, j, 'g')];
ppm2(i, j, 'b') = zmax * p[ppm(i, j, 'b')];
}
for (int n = 0; n < N; n++)
{
hist[n] = 0;
p[n] = 0;
}
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
hist[ppm2(i, j, 'r')]++;
hist[ppm2(i, j, 'g')]++;
hist[ppm2(i, j, 'b')]++;
}
for (int n = 0; n < N; n++)
for (int m = 0; m < n + 1; m++)
{
p[n] += hist[m] / (double)(3. * width * height);
}
ppm2.Flush("out.ppm");
std::ofstream ofs2("p.txt");
for (int n = 0; n < N; n++)
{
ofs2 << p[n] << std::endl;
}
return 0;
}
누적 분포 함수는
오! 생각보다 평평하게!
Reference
이 문제에 관하여(【화상 처리 100개 노크에 도전】Q.23. 히스토그램 평탄화), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/jajagacchi/items/7e03c1e0356a07096797
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
\sum_{i=0}^z h(i)/S \equiv p(z)
z' = z_{\rm max}p(z)
p(z) \equiv z'/z_{\rm max}
int main()
{
PPM ppm("imori.pnm");
int width = ppm.Get_width();
int height = ppm.Get_height();
int N = 256;
std::vector<int> hist(N);
std::vector<double> p(N);
for (int n = 0; n < N; n++)
{
hist[n] = 0;
p[n] = 0;
}
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
hist[ppm(i, j, 'r')]++;
hist[ppm(i, j, 'g')]++;
hist[ppm(i, j, 'b')]++;
}
for (int n = 0; n < N; n++)
for(int m=0; m<n+1; m++)
{
p[n] += hist[m]/(double)(3.*width*height);
}
std::ofstream ofs("p0.txt");
for (int n = 0; n < N; n++)
{
ofs << p[n] << std::endl;
}
int zmax = 255;
PPM ppm2(width, height);
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
ppm2(i, j, 'r') = zmax * p[ppm(i, j, 'r')];
ppm2(i, j, 'g') = zmax * p[ppm(i, j, 'g')];
ppm2(i, j, 'b') = zmax * p[ppm(i, j, 'b')];
}
for (int n = 0; n < N; n++)
{
hist[n] = 0;
p[n] = 0;
}
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
hist[ppm2(i, j, 'r')]++;
hist[ppm2(i, j, 'g')]++;
hist[ppm2(i, j, 'b')]++;
}
for (int n = 0; n < N; n++)
for (int m = 0; m < n + 1; m++)
{
p[n] += hist[m] / (double)(3. * width * height);
}
ppm2.Flush("out.ppm");
std::ofstream ofs2("p.txt");
for (int n = 0; n < N; n++)
{
ofs2 << p[n] << std::endl;
}
return 0;
}
Reference
이 문제에 관하여(【화상 처리 100개 노크에 도전】Q.23. 히스토그램 평탄화), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/jajagacchi/items/7e03c1e0356a07096797텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)