OpenCV获取图像直方图
发布日期:2021-05-14 15:16:28 浏览次数:27 分类:精选文章

本文共 4893 字,大约阅读时间需要 16 分钟。

直方图与图像均衡化技术教程

本文将详细介绍直方图统计、直方图均衡化以及直方图比较的原理与实现方法,并附带相应的OpenCV代码示例。

1. 直方图统计

在图像处理中,直方图是一种显示图像中像素分布情况的重要工具。直方图可以帮助我们了解图像中各个颜色(或灰度值)出现的频率和比例,从而为后续的图像增强和处理提供关系依据。

1.1 直方图的概念

直方图是一种统计图表,用于显示数据分布情况。对于图像来说,通常以灰度或RGB三色通道的分布情况为基础。假设图像的灰度范围为0-255,每个bin的范围是0-15,则bin的总数为16个。

1.2 OpenCV实现直方图统计

以下是OpenCV实现直方图统计的基本代码示例:

#include 
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_UNCHANGED);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
namedWindow("image", WINDOW_FREERATIO);
imshow("image", src);
vector
mv;
split(src, mv);
// 直方图计算
int histSize = 256;
Mat b_hist, g_hist, r_hist;
float range[] = {0, 255};
const float* histRanges = {range};
calcHist(&mv[0], 1, 0, Mat(), b_hist, 1, &histSize, histRanges, true, false);
calcHist(&mv[1], 1, 0, Mat(), g_hist, 1, &histSize, histRanges, true, false);
calcHist(&mv[2], 1, 0, Mat(), r_hist, 1, &histSize, histRanges, true, false);
// 直方图处理
Mat result = Mat::zeros(Size(600, 400), CV_8UC3);
int margin = 50;
int nm = result.rows - 2 * margin;
normalize(b_hist, b_hist, 0, nm, NORM_MINMAX, -1, Mat());
normalize(g_hist, g_hist, 0, nm, NORM_MINMAX, -1, Mat());
normalize(r_hist, r_hist, 0, nm, NORM_MINMAX, -1, Mat());
float step = 500.0 / 256.0;
for (int i = 0; i < 255; i++) {
line(result, Point(step*i, 50 + nm - b_hist.at
(i, 0)),
Point(step*(i+1), 50 + (nm - b_hist.at
(i+1, 0))),
Scalar(255, 0, 0), 2, 8, 0);
line(result, Point(step*i, 50 + nm - g_hist.at
(i, 0)), Point(step*(i+1), 50 + (nm - g_hist.at
(i+1, 0))), Scalar(0, 255, 0), 2, 8, 0); line(result, Point(step*i, 50 + nm - r_hist.at
(i, 0)), Point(step*(i+1), 50 + (nm - r_hist.at
(i+1, 0))), Scalar(0, 0, 255), 2, 8, 0); } imshow("histogramm", result); waitKey(0); destroyAllWindows(); return 0; }

1.3 直方图的主要步骤

  • 图像读取与分割:首先读取图像,分割成图片的各个通道(如红、绿、蓝)。
  • 直方图计算:利用OpenCV的calcHist函数计算各个通道的直方图。
  • 直方图归一化:为了方便比较,将直方图归一化至[0, 1]范围。
  • 直方图绘制:绘制并显示各个通道的直方图。
  • 2. 直方图均衡化

    直方图均衡化是一种图像增强技术,通过重新调整图像灰度分布,使图像的对比度更为明显,细节更加丰富。

    2.1 均衡化的原理

    直方图均衡化通过重新映射灰度值范围,将图像的对比度拉大,通常有两种方式:

    • 线性映射:新值 = (旧值 - min) * (max - min) / (max - min) + min
    • udios 呼吸法:适用于对对比度有偏差的图像(如灯光不均匀)

    2.2 OpenCV实现均衡化

    以下是实现直方图均衡化的代码示例:

    #include 
    #include
    using namespace cv;
    using namespace std;
    int main(int argc, char** argv) {
    Mat src = imread("E:/cats.jpg", IMREAD_UNCHANGED);
    if (src.empty()) {
    printf("image is empty!!!");
    return -1;
    }
    namedWindow("image", WINDOW_FREERATIO);
    imshow("image", src);
    Mat gray, dst;
    cvtColor(src, gray, COLOR_BGR2GRAY);
    equalizeHist(gray, dst);
    imshow("dst", dst);
    waitKey(0);
    destroyAllWindows();
    return 0;
    }

    2.3 均衡化步骤总结

  • 图像读取:读取输入图像。
  • 灰度化:将彩色图像转换为灰度图像。
  • 均衡化:使用equalizeHist函数进行直方图均衡化。
  • 显示结果:显示均衡化后的图像。
  • 3. 直方图比较

    在图像处理中,直方图比较是判断两幅图像是否相似的重要步骤。

    3.1 直方图比较方法

    常用比较方法:

  • 巴氏距离:适合度量直方图之间的相似度。
  • 相关系数:衡量直方图之间的相关性。
  • 卡方距离:基于卡方检验的离差衡量方式。
  • 交叉积:通过直方图的视度特征进行比较n维相似性。
  • 3.2 OpenCV实现直方图比较

    以下是使用OpenCV进行直方图比较的代码示例:

    #include 
    #include
    using namespace cv;
    using namespace std;
    int main(int argc, char** argv) {
    Mat src1 = imread("E:/cats.jpg", IMREAD_COLOR);
    Mat src2 = imread("E:/cat.png", IMREAD_COLOR);
    if (src1.empty() || src2.empty()) {
    printf("image is empty!!!");
    return -1;
    }
    namedWindow("src1", src1);
    namedWindow("src2", src2);
    int histSize[] = {256, 256, 256};
    int channels[] = {0, 1, 2};
    Mat hist1, hist2;
    float c1[] = {0, 255};
    float c2[] = {0, 255};
    float c3[] = {0, 255};
    const float* histRanges[] = {c1, c2, c3};
    calcHist(&src1, 1, channels, Mat(), hist1, 3, histSize, histRanges, true, false);
    calcHist(&src2, 1, channels, Mat(), hist2, 3, histSize, histRanges, true, false);
    // 均衡化
    normalize(hist1, hist1, 0, 1.0, NORM_MINMAX, -1, Mat());
    normalize(hist2, hist2, 0, 1.0, NORM_MINMAX, -1, Mat());
    // 巴氏距离
    double h12 = compareHist(hist1, hist2, HISTCMP_BHATTACHARYYA);
    double h11 = compareHist(hist1, hist1, HISTCMP_BHATTACHARYYA);
    printf("h12:%.2f, h11:%.2f\n", h12, h11);
    // 相关系数
    double c12 = compareHist(hist1, hist2, HISTCMP_CORREL);
    double c11 = compareHist(hist1, hist1, HISTCMP_CORREL);
    printf("c12:%.2f, c11:%.2f\n", c12, c11);
    waitKey(0);
    destroyAllWindows();
    return 0;
    }

    3.3 比较方法的优势

  • 巴氏距离:能够全面反映直方图的视度异同,适合量化相似度。
  • 相关系数:简单易计算,能够直观反映两直方图的趋势一致性。
  • 卡方距离:基于经验分布,能有效衡量离差。
  • 交叉积:强调直方图的视度特征,适合多维相似性比较n。
  • 4. 常用直方图比较工具

    在OpenCV中,可以使用compareHist函数来实现直方图比较,支持以下方法:

  • 相关系数法:计算直方图的相关系数,值越高说明相似。
  • 巴氏距离法:综合考虑直方图的整体分布,值越小代表相似。
  • 卡方距离法:基于卡方统计量,适合单峰分布数据。
  • 交叉积法:计算两个直方图的乘积结果,值越大表示更高的相似度。
  • 通过以上方法,我们可以从多个维度全面衡量图像的相似度,从而为图像处理提供更精准的依据。

    上一篇:OpenCV进行视频读写
    下一篇:OpenCV图像通道的合并与分离

    发表评论

    最新留言

    不错!
    [***.144.177.141]2025年04月18日 00时25分57秒