opencv 绘制直方图 并 重写鼠标事件 得到百分比,像素值(一)
文章目录
提示:以下是本篇文章正文内容,下面案例可供参考
一、opencv直方图计算函数即绘制函数参数解释解析
1、calcHist 直方图计算函数
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 );
参数列表 | 参数功能 |
---|---|
1、images | 你想要获取直方图的原图像 |
2、nimages | 输入图像的个数 |
3、channels | 获取哪一个通道 |
4、mask | 可选的操作掩码 |
5、hist | 接收直方图结构 |
6、dims | 直方图的通道数 |
7、histSize | 直方图的尺寸 |
8、ranges | 直方图的范围 |
9、uniform | 是否做归一化处理,默认为是 |
10、accumlate | 是否累积像素值个数 |
2、rectangle() 绘制矩形 可以实现填充直方图
void rectangle(CV_IN_OUT Mat& img, Rect rec,
const Scalar& color, int thickness = 1,
int lineType = LINE_8, int shift = 0);
参数列表 | 参数功能 |
---|---|
1、img | 绘制在那一张图片上 |
2、rec | 绘制的矩形大小 |
3、color | 绘制的颜色 |
4、thickness | 绘制的线条宽度 |
5、lineType | 绘制的线型 |
6、shift | 坐标的精度,默认为0 |
3、line() 绘制轮廓 可以实现绘制直方图的轮廓
void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,
int thickness = 1, int lineType = LINE_8, int shift = 0);
参数列表 | 参数功能 |
---|---|
1、img | 绘制在那一张图片上 |
2、pt1 | 绘制的起始点 |
3、平台 | 绘制的结束点 |
4、color | 绘制的颜色 |
5、thickness | 绘制的线条宽度 |
6、lineType | 绘制的线型 |
7、shift | 坐标的精度,默认为0 |
二、功能代码
1、计算并绘制灰度直方图
如果说需要的是直方图的轮廓 而不是填充的那只要把rectangle 函数替换成line 即可
QImage HistogramView::DrawGrayHistogram(QImage image)
{
cv::Mat gray;
cv::Mat src = this->QImage2Mat(image);
cv::cvtColor(src, gray, CV_BGR2GRAY);
this->m_Flag = GRAY;
const int channels[] = { 0 };
int dims = 1; //设置直方图维度
const int histSize[] = { 256 }; //直方图每一个维度划分的柱条的数目
float pranges[] = { 0, 255 };//每个纬度的取值区间
const float* ranges[] = { pranges };
cv::calcHist(&gray, 1, channels, cv::Mat(), this->m_Gray_Hist, dims, histSize, ranges, true, false);
int scale = 2;
int hist_height = 256;
cv::Mat hist_img = cv::Mat::zeros(hist_height, 256 * scale, CV_8UC3); //创建一个黑底的8位的3通道图像,高256,宽256*2
double max_val;
float total_pix=src.rows*src.cols;
cv::minMaxLoc(this->m_Gray_Hist, 0, &max_val, 0, 0);//计算直方图的最大像素值
//将像素的个数整合到 图像的最大范围内
//遍历直方图得到的数据
for (int i = 0; i < 256; i++)
{
float bin_val = this->m_Gray_Hist.at<float>(i); //遍历hist元素(注意hist中是float类型)
int intensity = cvRound(bin_val*hist_height / max_val); //绘制高度
cv::rectangle(hist_img, cv::Point(i*scale, hist_height - 1), cv::Point((i + 1)*scale - 1, hist_height - intensity), cv::Scalar(255, 255, 255));//绘制直方图
}
/*绘制轮廓
for (int i = 0; i < 255; i++)
{
float bin_val = this->m_Gray_Hist.at<float>(i); //遍历hist元素(注意hist中是float类型)
float bin_val2 = this->m_Gray_Hist.at<float>(i+1); //后一个像素值
int intensity = cvRound(bin_val*hist_height / max_val); //绘制高度
int intensity2 = cvRound(bin_val2*hist_height / max_val);
cv::line(hist_img, cv::Point(i*scale,hist_height - intensity), cv::Point((i + 1)*scale - 1,hist_height - intensity2), cv::Scalar(255, 255, 255));
}
*/
this->m_totalpixeldata->setText(QString("%1").arg(total_pix));
return this->Mat2QImage(hist_img);
}
2、计算并绘制RGB 直方图
QImage HistogramView::DrawBGRHistogram(QImage image, int flag)
{
if(image.isNull())
return image;
cv::Mat src = this->QImage2Mat(image);
std::vector<cv::Mat> bgr_planes;
int dims = 1;
const int histSize[] = { 256 };
float pranges[] = { 0, 255 };
const float* ranges[] = { pranges };
cv::split(src, bgr_planes);
int scale = 2;
int hist_height = 256;
cv::Mat hist_img = cv::Mat::zeros(hist_height, 256 * scale, CV_8UC3); //创建一个黑底的8位的3通道图像,高256,宽256*2
double max_val;
float total_pix=src.rows*src.cols;
switch(flag)
{
case BLUE:
this->m_Flag = BLUE;
cv::calcHist(&bgr_planes[0], 1,0,cv::Mat(),this->m_Blue_Hist,dims, histSize, ranges, true, false); //计算直方图
cv::minMaxLoc(m_Blue_Hist,0,&max_val,0,0);
for (int i = 0; i < 256; i++)
{
float bin_val = m_Blue_Hist.at<float>(i); //遍历hist元素(注意hist中是float类型)
int intensity = cvRound(bin_val*hist_height / max_val); //绘制高度
cv::rectangle(hist_img, cv::Point(i*scale, hist_height - 1), cv::Point((i + 1)*scale - 1, hist_height - intensity), cv::Scalar(255, 255, 255));//绘制直方图
}
break;
case GREEN:
this->m_Flag = GREEN;
cv::calcHist(&bgr_planes[1], 1,0,cv::Mat(),this->m_Green_Hist,dims, histSize, ranges, true, false);
cv::minMaxLoc(this->m_Green_Hist,0,&max_val,0,0);
for (int i = 0; i < 256; i++)
{
float bin_val = this->m_Green_Hist.at<float>(i); //遍历hist元素(注意hist中是float类型)
int intensity = cvRound(bin_val*hist_height / max_val); //绘制高度
cv::rectangle(hist_img, cv::Point(i*scale, hist_height - 1), cv::Point((i + 1)*scale - 1, hist_height - intensity), cv::Scalar(255, 255, 255));//绘制直方图
}
break;
case RED:
this->m_Flag = RED;
cv::calcHist(&bgr_planes[2], 1,0,cv::Mat(),this->m_Red_Hist,dims, histSize, ranges, true, false);
cv::minMaxLoc(this->m_Red_Hist,0,&max_val,0,0);
for (int i = 0; i < 256; i++)
{
float bin_val = this->m_Red_Hist.at<float>(i); //遍历hist元素(注意hist中是float类型)
int intensity = cvRound(bin_val*hist_height / max_val); //绘制高度
cv::rectangle(hist_img, cv::Point(i*scale, hist_height - 1), cv::Point((i + 1)*scale - 1, hist_height - intensity), cv::Scalar(255, 255, 255));//绘制直方图
}
break;
}
this->m_totalpixeldata->setText(QString("%1").arg(total_pix));
return this->Mat2QImage(hist_img);
}
三、效果图
1、原图
2、灰度直方图
填充效果
轮廓效果
2、RGB 直方图