直方图:图像像素值的统计表。灰度图像有256个条目(容器)
获取直方图:
void calcHist( const Mat* images, int nimages, const int* channels, InputArray mask,
OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform = true, bool accumulate = false );
获取数组的最大值和最小值:
void cvMinMaxLoc( const CvArr* arr, double* min_val, double* max_val,
CvPoint* min_loc=NULL, CvPoint* max_loc=NULL, const CvArr* mask=NULL );
arr
输入数组, 单通道或者设置了 COI 的多通道。
min_val
指向返回的最小值的指针。
max_val
指向返回的最大值的指针。
min_loc
指向返回的最小值的位置指针。
max_loc
指向返回的最大值的位置指针。mask
选择一个子数组的操作掩模。
画线函数:
void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,
int thickness = 1, int lineType = LINE_8, int shift = 0);
二值化函数:
void cvThreshold( const CvArr* src, CvArr* dst, double threshold,
double max_value, int threshold_type );
src 原始数组
(单通道, 8-比特
of 32-比特 浮点数).
dst 输出数组,必须与
src 的类型一致,或者为
8-比特.
threshold 阈值
max_value 使用
CV_THRESH_BINARY 和
CV_THRESH_BINARY_INV 的最大值.
threshold_type 阈值类型
(见讨论)
函数 cvThreshold
对单通道数组应用固定阈值操作。该函数的典型应用是对灰度图像
进行阈值操作得到二值图像。(cvCmpS
也可以达到此目的) 或者是去掉噪声,例如过滤
很小或很大象素值的图像点。本函数支持的对图像取阈值的方法由 threshold_type 确
定:
threshold_type=CV_THRESH_BINARY:
dst(x,y) = max_value, if src(x,y)>threshold
0, otherwise
threshold_type=CV_THRESH_BINARY_INV:
dst(x,y) = 0, if src(x,y)>threshold
max_value, otherwise
threshold_type=CV_THRESH_TRUNC:
dst(x,y) = threshold, if src(x,y)>threshold
src(x,y), otherwise
threshold_type=CV_THRESH_TOZERO:
dst(x,y) = src(x,y), if (x,y)>threshold
0, otherwise
threshold_type=CV_THRESH_TOZERO_INV:
dst(x,y) = 0, if src(x,y)>threshold
src(x,y), otherwise
#include <stdio.h>
#include <iostream>
#include "opencv2/opencv.hpp"
#include "histogram.h"
using namespace std;
using namespace cv;
int main()
{
Histogram1D h;
Mat image;
image = imread("D:/1.jpg", 0);
/*
MatND histo = h.getHistogram(image);
for (int i = 0; i < 256;i++)
//cout << "Value" << i << "=" << hist.at<float>(i) << endl;
*/
/*namedWindow("Histogram");
imshow("Histogram", h.getHistogramImage(image));
*/
/********************************************************
二值化
********************************************************/
Mat thresholded;
threshold(image, thresholded, 60, 255, THRESH_BINARY);
namedWindow("thresholded");
imshow("thresholded", thresholded);
waitKey(0);
}
#pragma once
#ifndef HISTOGRAM_H
#define HISTOGRAM_H
#include "opencv2/opencv.hpp"
using namespace cv;
class Histogram1D
{
private:
int histSize[1]; //项的数量
float hranges[2]; //像素的最小以及最大值
const float *ranges[1]; //
int channels[1]; //通道
public:
Histogram1D() //构造函数
{
histSize[0] = 256;
hranges[0] = 0.0;
hranges[1] = 255.0;
ranges[0] = hranges;
channels[0] = 0; //默认考察0通道
}
MatND getHistogram(const Mat &image)
{
MatND hist; //hist 是一个一维数组
calcHist(&image, 1, channels, Mat(), hist, 1, histSize, ranges);
/*
CV_EXPORTS void calcHist( const Mat* images, int nimages, const int* channels, InputArray mask,
OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform = true, bool accumulate = false );
CV_EXPORTS void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask,
SparseMat& hist, int dims, const int* histSize, const float** ranges, bool uniform = true, bool accumulate = false);
CV_EXPORTS_W void calcHist(InputArrayOfArrays images, const std::vector<int>& channels, InputArray mask, OutputArray hist,
const std::vector<int>& histSize, const std::vector<float>& ranges, bool accumulate = false);
image。输入的图像的指针,可以是多幅图像,所有的图像必须有同样的深度(CV_8U or CV_32F)。同时一副图像可以有多个channes。
narrays。输入的图像的个数。
channels。用来计算直方图的channes的数组。比如输入是2副图像,第一副图像有0,1,2共三个channel,第二幅图像只有0一个channel,
那么输入就一共有4个channes,如果int channels[3] = {3, 2, 0},那么就表示是使用第二副图像的第一个通道和第一副图像的第2和第0个通道来计
算直方图。
mask。掩码。如果mask不为空,那么它必须是一个8位(CV_8U)的数组,并且它的大小的和arrays[i]的大小相同,值为1的点将用来计算
直方图。
hist。计算出来的直方图
dims。计算出来的直方图的维数。
histSize。在每一维上直方图的个数。简单把直方图看作一个一个的竖条的话,就是每一维上竖条的个数。
ranges。用来进行统计的范围。比如
float rang1[] = {0, 20};
float rang2[] = {30, 40};
const float *rangs[] = {rang1, rang2};那么就是对0,20和30,40范围的值进行统计。
uniform。每一个竖条的宽度是否相等
*/
return hist;
}
Mat getHistogramImage(const Mat &image)
{
// Compute histogram first
MatND hist = getHistogram(image);
// Get min and max bin values
double maxVal = 0;
double minVal = 0;
minMaxLoc(hist, &minVal, &maxVal, 0, 0);
// Image on which to display histogram
Mat histImg(histSize[0], histSize[0], CV_8U, Scalar(255));
// set highest point at 90% of nbins
int hpt = static_cast<int>(0.9*histSize[0]);
// Draw vertical line for each bin
for (int h = 0; h < histSize[0]; h++) {
float binVal = hist.at<float>(h);
int intensity = static_cast<int>(binVal*hpt / maxVal);
line(histImg, Point(h, histSize[0]), Point(h, histSize[0] - intensity), Scalar::all(0));
/*
void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,
int thickness = 1, int lineType = LINE_8, int shift = 0);
*/
}
return histImg;
}
};
#endif // !HISTOGRAM_H