白黒濃淡画像を入力とし,その画像の平均値,中央値,最頻値,標準偏差を出力するプログラムを
作成せよ.3 種類の画像に適用し,求めた量で各画像のどのような性質を知ることができているのか 考察せよ.
というものなのですが、中央値、最頻値を求め方がわかりません。下記のコードは教授の書いたものなのですが、ヒストグラムを作っているのはなぜでしょうか、お願いします。
#include "common.h"
void average_sd(const cv::Mat_<uchar> image, double &average, double &sd)
{
average = .0;
sd = .0;
for (int y = 0; y < image.rows; ++y)
{
for (int x = 0; x < image.cols; ++x)
{
average += image(y,x); //ここで各画素の値を足す
}
}
average /= image.total(); //足された値を画素数(=image.total())で割って平均にしてある
for (int y = 0; y < image.rows; ++y)
{
for (int x = 0; x < image.cols; ++x)
{
sd += ((average-image(y,x))*(average - image(y,x))); //ここで分散の定義に従って適切な処理をする
}
}
sd /= image.total(); //画素数で割って
sd = sqrt(sd); //平方根を取る
}
int main(void)
{
cv::Mat_<uchar> image = cv::imread("flower.JPG", 0);
cv::Mat_<uchar> image2 = image.clone();
image2 /= 2; //各画素の画素値を半分にした画像を作成(結果的に,平均値は半分になる.標準偏差は??)
cv::imshow("input", image);
cv::imshow("input2", image2);
double average, sd;
double average2, sd2;
average_sd(image, average, sd);
average_sd(image2, average2, sd2);
//二つの画像の平均値と標準偏差を画面に表示
//標準出力がファイルにリダイレクトされているので,
//fprintf("%lf, %lf, ¥n", average, sd);
//↑これのコメントを外せばファイルに出力されます.
fprintf(stderr, "%lf, %lf, ¥n", average, sd);
fprintf(stderr, "%lf, %lf, ¥n", average2, sd2);
//以降では,最頻値と中央値を求めるためにヒストグラムを作成している
cv::Mat_<int> hist = cv::Mat::zeros(256, 1, CV_32SC1);
for (int y = 0; y < image.rows; ++y)
{
for (int x = 0; x < image.cols; ++x)
{
int tmp = image(y, x);
if (tmp >= 0 && tmp < 256)
{
hist(tmp, 0)++;
}
}
}
for (int y = 0; y < hist.rows; ++y)
{
//濃度値と頻度を画面に表示.2行で同じことをやっているが,
//一つはエラーコンソール,一つは標準出力であり,標準出力は実行時オプションで指定してあるファイルに出力される.
fprintf(stderr, "%d, %d, ¥n", y, hist(y, 0));
printf("%d, %d ¥n", y, hist(y, 0));
}
cv::waitKey();
return 0;
}