依次遍历图像的像素点,存储不同灰度级的像素点个数
代码(包含画直方图):
bool calcHistograph(Mat img){
if (!img.data)
return false;
Mat gray;
if (img.channels() == 1)
img.copyTo(gray);
else
cvtColor(img, gray, CV_BGR2GRAY);
Mat histogram(500, 520, CV_8UC1, Scalar(0, 0, 0));
float hist[256] = { 0 };
for (int i = 0; i < gray.rows; i++)
{
for (int j = 0; j < gray.cols; j++)
{
hist[gray.at<uchar>(i, j)] ++;
}
}
float max = 0;
for (int i = 0; i < 256; i++)
{
if (hist[i] > max)
max = hist[i];
}
for (int i = 0; i < 256; i++)
{
line(histogram, Point(i * 2, 500), Point(i * 2,500. - hist[i] / max * 500.), Scalar(255));
line(histogram, Point(i * 2 + 1, 500), Point(i * 2 + 1, 500. - hist[i] / max * 500.), Scalar(255));
}
imshow("histogram", histogram);
waitKey(10);
return true;
}
定义必要的函数参数,调用calcHist()函数
代码(包含画直方图):
//计算直方图数据 取数据:hist.at<float>(i)
bool calcImgHistData(const Mat &img, MatND &hist, MatND &hist_prob){
if (!img.data)
return false;
const int channels[1] = { 0 };
const int histSize[1] = { 256 };
float hrange[2] = { 0, 256 };
const float *range[1] = { hrange };
calcHist(&img, 1, channels, Mat(), hist, 1, histSize, range);
Mat histogram(500, 520, CV_8UC1, Scalar(0, 0, 0));
float max = 0;
for (int i = 0; i < 256; i++)
{
if (hist.at<float>(i) > max)
max = hist.at<float>(i);
}
for (int i = 0; i < 256; i++)
{
line(histogram, Point(i * 2, 500), Point(i * 2,500. - hist.at<float>(i) / max * 500.), Scalar(255));
line(histogram, Point(i * 2 + 1, 500), Point(i * 2 + 1, 500. - hist.at<float>(i) / max * 500.), Scalar(255));
}
imshow("histogram", histogram);
waitKey(10);
return true;
}
注意
float hrange[2] = { 0, 256 };
不少童鞋都将256错写成255,结果丢失了灰度级为255的数据