0
点赞
收藏
分享

微信扫一扫

OpenCV + CPP 系列(十八)直方图 与 直方图均衡化


文章目录

  • ​​一、函数介绍​​
  • ​​calcHist​​
  • ​​cvRound()、cvFloor()、cvCeil()函数详解​​
  • ​​二、直方图显示​​
  • ​​一维直方图​​
  • ​​二维直方图​​
  • ​​三、直方图均衡化​​


关于opencv-python 有关直方图查看


OpenCV—python 颜色空间(RGB,HSV,Lab)与 颜色直方图


OpenCV—python 颜色直方图与直方图均衡化

一、函数介绍

calcHist

该函数可以一次统计多张图片每个通道的灰度值数据


const Mat*

​images​​,    输入需要计算的矩阵(CV_8U或 CV_32F)


int

​nimages​​,       源图像的数目


const int*

​channels​​,    通道列表。通道数必须与直方图维数匹配,从0开始


InputArray

​mask​​,     掩码(不需要填Mat())


OutputArray

​hist​​,    输出直方图


int

​dims​​,        直方图的维度


const int*

​histSize​​,   数组,即histSize[i]表示第i个维度上bin的个数(一维一般为256)


const float**

​ranges​​,   一般为(0,256)


bool

​uniform = true​​,   标识,用于说明直方条bin是否是均匀等宽的。


bool

​accumulate = false​​ 累积标识。多幅图像时,累积计算一个简单的直方图,或者及时更新直方图。


)


cvRound()、cvFloor()、cvCeil()函数详解

函数cvRound()、cvFloor()、cvCeil()都是按照一种舍入方式将浮点型数据转换为整型数据。

  • cvRound():返回跟参数最接近的整数值,即四舍五入;(2.5 ->2, 2.51->3)
  • cvFloor() :返回不大于参数的最大整数值,即向下取整;(2.5 ->2)
  • cvCeil() :返回不小于参数的最小整数值,即向上取整;(2.5 ->3)

二、直方图显示

头文件 ​​quick_opencv.h​​:声明类与公共函数

#pragma once
#include <opencv2\opencv.hpp>
using namespace cv;

class QuickDemo {
public:
...
void show_histogram_Demo(Mat& image);
void show_histogram2d_Demo(Mat& image);
};

主函数调用该类的公共成员函数

#include <opencv2\opencv.hpp>
#include <quick_opencv.h>
#include <iostream>
using namespace cv;


int main(int argc, char** argv) {
Mat src = imread("D:\\Desktop\\pandas.jpg");
if (src.empty()) {
printf("Could not load images...\n");
return -1;
}
namedWindow("input", WINDOW_NORMAL);
imshow("input", src);

QuickDemo qk;

...
qk.show_histogram_Demo(src);
qk.show_histogram2d_Demo(src);
waitKey(0);
destroyAllWindows();
return 0;
}

一维直方图

源文件 ​​quick_demo.cpp​​:实现类与公共函数

void QuickDemo::show_histogram_Demo(Mat& image) {
std::vector<Mat> bgr_plane;
split(image, bgr_plane);

const int channels[1] = { 0 };
const int bins[1] = { 256 }; //bins数据分成的等级
float hranges[2] = { 0,256 };
const float* ranges[1] = { hranges };

Mat b_hist;
Mat g_hist;
Mat r_hist;

// 计算 B,G,R三个通道的直方图
calcHist(&bgr_plane[0], 1, 0, Mat(), b_hist, 1, bins, ranges);
calcHist(&bgr_plane[1], 1, 0, Mat(), g_hist, 1, bins, ranges);
calcHist(&bgr_plane[2], 1, 0, Mat(), r_hist, 1, bins, ranges);

//显示直方图
int hist_w = 512;
int hist_h = 400;
int bin_w = cvRound((double)hist_w/bins[0]);
Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3);

//归一化直方图
normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());

//绘制直方图曲线
for (int i = 1; i < bins[0]; i++) {
line(histImage, \
Point(bin_w * (i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))), \
Point(bin_w * i, hist_h - cvRound(b_hist.at<float>(i))), \
Scalar(255, 0, 0), 2, 8, 0);
line(histImage, \
Point(bin_w * (i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))), \
Point(bin_w * i, hist_h - cvRound(g_hist.at<float>(i))), \
Scalar(0, 255, 0), 2, 8, 0);
line(histImage, \
Point(bin_w * (i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))), \
Point(bin_w * i, hist_h - cvRound(r_hist.at<float>(i))), \
Scalar(0, 0, 255), 2, 8, 0);
}
imshow("histImage", histImage);
}

OpenCV + CPP 系列(十八)直方图 与 直方图均衡化_可视化

二维直方图

源文件 ​​quick_demo.cpp​​:实现类与公共函数

void QuickDemo::show_histogram2d_Demo(Mat& image) {
Mat hsv, hs_hist;
cvtColor(image, hsv, COLOR_BGR2HSV);

int hbin = 30, sbin = 32;
int hist_bins[] = { hbin , sbin };
float h_range[] = { 0,180 };
float s_range[] = { 0,256 };
const float* hs_ranges[] = { h_range,s_range };
int hs_channels[] = { 0,1 };
calcHist(&hsv, 1, hs_channels, Mat(), hs_hist, 2, hist_bins, hs_ranges, true, false);

double maxVal = 0;
minMaxLoc(hs_hist, 0, &maxVal, 0, 0);
int scale = 10;
Mat hist_2d_image = Mat::zeros(sbin * scale, hbin * scale, CV_8UC3);
for (int h = 0; h < hbin; h++) {
for (int s = 0; s < sbin; s++) {
float binVal = hs_hist.at<float>(h, s);
int intensity = cvRound(binVal * 255 / maxVal);
rectangle(hist_2d_image,
Point(h * scale, s * scale),
Point((h + 1) * scale, (s + 1) * scale),
Scalar::all(intensity),
-1
);
}
}
imshow("hist_2d_image0", hist_2d_image);
applyColorMap(hist_2d_image, hist_2d_image, 2);
imshow("hist_2d_image1", hist_2d_image);
}

OpenCV + CPP 系列(十八)直方图 与 直方图均衡化_2d_02

三、直方图均衡化

这里只是演示了图像的全局直方图均衡化

void QuickDemo::histogram_eq_Demo(Mat& image) {
//灰度图像直方图均衡化
Mat gray, dst;
cvtColor(image, gray, COLOR_BGR2GRAY);
equalizeHist(gray, dst);
imshow("gray", gray);
imshow("dst", dst);

// 彩色图像直方图均衡化
Mat hsv, hsv_dst;
std::vector<Mat> hsv_split;
cvtColor(image.clone(), hsv, COLOR_BGR2HSV);
split(hsv, hsv_split);
equalizeHist(hsv_split[2], hsv_split[2]);
merge(hsv_split, hsv);
cvtColor(hsv, hsv_dst, COLOR_HSV2BGR);
imshow("hsv_dst", hsv_dst);
}

OpenCV + CPP 系列(十八)直方图 与 直方图均衡化_c++_03


举报

相关推荐

0 条评论