OpenCV(十八):图像直方图

这篇具有很好参考价值的文章主要介绍了OpenCV(十八):图像直方图。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.直方图统计

2.直方图均衡化

3.直方图匹配


1.直方图统计

       直方图统计是一种用于分析图像或数据的统计方法,它通过统计每个数值或像素值的频率分布来了解数据的分布情况。

OpenCV(十八):图像直方图,Android之OpenCV,opencv,c++

在OpenCV中,可以使用函数cv::calcHist()来计算图像的直方图。

calcHist() 函数的原型如下:

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);

参数说明:

  • images: 输入图像数组,可以是单张图像或多张图像的数组。

  • nimages: 输入图像的数量。

  • channels: 要计算直方图的通道索引数组。例如,对于灰度图像,只有一个通道,因此 channels 设置为 {0};而对于彩色图像,可以指定 {0, 1, 2} 对应于 B、G、R 三个通道。

  • mask: 掩码图像,用于指定计算直方图的区域。如果不需要使用掩码,可以传入空的 Mat()。

  • hist: 输出的直方图,用于存储计算结果。

  • dims: 直方图的维度,通常为 1。

  • histSize: 直方图的大小,即每个维度的条目数量。

  • ranges: 直方图的范围,可以使用 {0, 256} 表示像素值范围为 [0, 256)。

  • uniform: 指示直方图条目是否均匀分布,默认为 true。

  • accumulate: 指示是否累积直方图,默认为 false。

下面是一个示例代码,展示如何使用cv::calcHist()函数计算图像的直方图:

#include <opencv2/opencv.hpp>
void hist(Mat image){
// 定义直方图参数
int histSize = 256; // 直方图条目数量
const int channels[1]={0};//通道索引
float range[] = { 0, 256 }; // 像素值范围
const float* histRange = { range };
bool uniform = true; // 直方图条目是否均匀分布
bool accumulate = false; // 直方图是否累积
// 计算直方图
cv::Mat hist;
cv::calcHist(&image, 1, channels, cv::Mat(), hist, 1, &histSize, &histRange, uniform, accumulate);

// 绘制直方图
int histWidth = 512;
int histHeight = 400;
int binWidth = cvRound((double)histWidth / histSize);
cv::Mat histImage(histHeight, histWidth, CV_8UC4, cv::Scalar(0, 0, 0));
cv::normalize(hist, hist, 0, histImage.rows, cv::NORM_MINMAX, -1, cv::Mat());
for (int i = 1; i < histSize; ++i){
cv::line(histImage, cv::Point(binWidth * (i - 1), histHeight - cvRound(hist.at<float>(i - 1))),
cv::Point(binWidth * (i), histHeight - cvRound(hist.at<float>(i))),
cv::Scalar(255, 255, 255), 2, 8, 0);
}
// 显示直方图
cv::imwrite("/sdcard/DCIM/histImage.jpg", histImage);
}

示例代码中将原图像image转换为单通道灰度图像。然后定义了直方图的参数,包括直方图条目数量、像素值范围、均匀性和累积性。接下来使用 cv::calcHist() 函数计算了图像的直方图,存储在 hist 中。最后,通过绘制直方图数据到 histImage 中,实现了直方图的可视化。

OpenCV(十八):图像直方图,Android之OpenCV,opencv,c++

2.直方图均衡化

        直方图均衡化是一种用于增强图像对比度的图像处理技术。它通过重新分布图像像素值的频率分布来增强图像的亮度和细节。

在OpenCV中,可以使用cv::equalizeHist()函数来进行直方图均衡化。该函数的原型如下:

void equalizeHist(InputArray src, OutputArray dst);

参数说明:

  • src:需要直方图均衡化的CV 8UC1图像。

  • dst: 直方图均衡化后的输出图像,与src具有相同尺寸和数据类型

下面是一个示例代码,展示如何使用cv::equalizeHist()函数来进行直方图均衡化:

#include <opencv2/opencv.hpp>
void drawHist(Mat &hist,string name){//归一化并绘制直方图函数
    int histSize = 256;  // 直方图条目数量
    // 绘制直方图
    int histWidth = 512;
    int histHeight = 400;
    int binWidth = cvRound((double)histWidth / histSize);
    cv::Mat histImage(histHeight, histWidth, CV_8UC4, cv::Scalar(0, 0, 0));
    cv::normalize(hist, hist, 0, histImage.rows, cv::NORM_MINMAX, -1, cv::Mat());

    for (int i = 1; i < histSize; ++i)
    {
        cv::line(histImage, cv::Point(binWidth * (i - 1), histHeight - cvRound(hist.at<float>(i - 1))),
                 cv::Point(binWidth * (i), histHeight - cvRound(hist.at<float>(i))),
                 cv::Scalar(255, 255, 255), 2, 8, 0);
    }
    // 显示直方图
    cv::imwrite("/sdcard/DCIM/"+name+".jpg", histImage);

}
void EqualImage(Mat image){
    //灰度化
    Mat gray;
    cvtColor(image,gray,COLOR_BGR2GRAY);
    //将灰度图进行直方图均衡化
    Mat equalImg;
    equalizeHist(gray,equalImg);
    cv::imwrite("/sdcard/DCIM/equalImg.jpg", equalImg);
    // 定义直方图参数
    int histSize = 256;  // 直方图条目数量
    const int channels[1]={0};//通道索引
    float range[] = { 0, 256 };  // 像素值范围
    const float* histRange = { range };
    bool uniform = true;  // 直方图条目是否均匀分布
    bool accumulate = false;  // 直方图是否累积

    // 计算直方图
    cv::Mat hist;
    cv::calcHist(&equalImg, 1, channels, cv::Mat(), hist, 1, &histSize, &histRange, uniform, accumulate);

    drawHist(hist,"hist1");

}

示例代码中将原图像image转换为单通道灰度图像,然后将灰度图进行直方图均衡化,之后定义了直方图的参数,包括直方图条目数量、像素值范围、均匀性和累积性。接下来使用 cv::calcHist() 函数计算了图像的直方图,存储在 hist 中。最后,通过绘制直方图数据到 histImage 中,实现了直方图的可视化。

OpenCV(十八):图像直方图,Android之OpenCV,opencv,c++

3.直方图匹配

       直方图匹配(Histogram Matching)是一种图像处理技术,用于将一副图像的直方图映射到另一副图像上,从而使它们的亮度分布或颜色分布相似。该技术常用于图像增强、风格转换、颜色校正等应用中。

以下是一个使用OpenCV实现直方图匹配的示例代码:


#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

void drawHist(Mat &hist,string name){//归一化并绘制直方图函数
    int histSize = 256;  // 直方图条目数量
    // 绘制直方图
    int histWidth = 512;
    int histHeight = 400;
    int binWidth = cvRound((double)histWidth / histSize);
    cv::Mat histImage(histHeight, histWidth, CV_8UC4, cv::Scalar(0, 0, 0));
    cv::normalize(hist, hist, 0, histImage.rows, cv::NORM_MINMAX, -1, cv::Mat());

    for (int i = 1; i < histSize; ++i)
    {
        cv::line(histImage, cv::Point(binWidth * (i - 1), histHeight - cvRound(hist.at<float>(i - 1))),
                 cv::Point(binWidth * (i), histHeight - cvRound(hist.at<float>(i))),
                 cv::Scalar(255, 255, 255), 2, 8, 0);
    }
    // 显示直方图
    cv::imwrite("/sdcard/DCIM/"+name+".jpg", histImage);

}
void  Histogram_matching(Mat img1,Mat img2){
    Mat hist1,hist2;
    //计算两张图像直方图
    const int channels[1]={0};
    float inRanges[2]={0,255};
    const float *ranges[1]={inRanges};
    const int bins[1]={256};
    calcHist(&img1,1,channels,Mat(),hist1,1,bins,ranges);
    calcHist(&img2,1,channels,Mat(),hist2,1,bins,ranges);
    //归一化两张图像的直方图
    drawHist(hist1,"hist1");
    drawHist(hist2,"hist2");
    //计算两张图像直方图的累计概率
    float hist1_cdf[256]={hist1.at<float>(0)};
    float hist2_cdf[256]={hist2.at<float>(0)};
    for(int i=1;i<256;i++){
        hist1_cdf[i]=hist1_cdf[i-1]+hist1.at<float>(i);
        hist2_cdf[i]=hist2_cdf[i-1]+hist1.at<float>(i);
    }
    //构建累积概率误差矩阵
    float diff_cdf[256][256];
    for(int i=0; i<256; i++){
        for(int j=0; j<256; j++){
            diff_cdf[i][j] = fabs(hist1_cdf[i] - hist2_cdf[j]);
        }
    }
    uchar lutone[256];
    for(int i=0;i<256;i++){
        //查找源灰度级为i的映射灰度
        //和i的累积概率差值最小的规定化灰度
        float min=diff_cdf[i][0];
        int index=0;
        //寻找累积概率误差矩阵中每一行中的最小值
        for(int j=1;j<256;j++){
            if(min>diff_cdf[i][j]){
                min=diff_cdf[i][j];
                index=j;
            }
        }
        lutone[i]=index;
    }
    //生成LUT映射表
    Mat lut(1,256,CV_8UC1,lutone);
    Mat result,hist3;
    LUT(img1,lut,result);
    imwrite("/sdcard/DCIM/result.png",result);
    calcHist(&result,1,channels,Mat(),hist3,1,bins,ranges);
    drawHist(hist3,"hist3");

}

示例代码:计算原始图像和目标图像的直方图,归一化直方图,计算累计直方图,构建累积概率误差矩阵,根据最小差值构建映射表,最后将原始图像的灰度级根据映射表调整为目标图像的灰度级。下面是原始图像和直方图匹配后图片,可以看出直方图匹配后的图片使得图像中的细节更加清晰可见。

OpenCV(十八):图像直方图,Android之OpenCV,opencv,c++                  OpenCV(十八):图像直方图,Android之OpenCV,opencv,c++

              原图                                            直方图匹配的结果文章来源地址https://www.toymoban.com/news/detail-695544.html

到了这里,关于OpenCV(十八):图像直方图的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python Opencv实践 - 图像直方图均衡化

         

    2024年02月11日
    浏览(43)
  • Python-OpenCV中的图像处理-图像直方图

    通过直方图你可以对整幅图像的灰度分布有一个整体的了解。直方图的 x 轴是灰度值( 0 到 255), y 轴是图片中具有同一个灰度的点的数目。 BINS:上面的直方图显示了每个灰度值对应的像素数。如果像素值为 0到255,你就需要 256 个数来显示上面的直方图。但是,如果你不需

    2024年02月12日
    浏览(71)
  • OpenCV-Python中的图像处理-图像直方图

    通过直方图你可以对整幅图像的灰度分布有一个整体的了解。直方图的 x 轴是灰度值( 0 到 255), y 轴是图片中具有同一个灰度的点的数目。 BINS:上面的直方图显示了每个灰度值对应的像素数。如果像素值为 0到255,你就需要 256 个数来显示上面的直方图。但是,如果你不需

    2024年02月12日
    浏览(61)
  • Python-OpenCV中的图像处理-直方图

    通过直方图你可以对整幅图像的灰度分布有一个整体的了解。直方图的 x 轴是灰度值( 0 到 255), y 轴是图片中具有同一个灰度的点的数目。 BINS:上面的直方图显示了每个灰度值对应的像素数。如果像素值为 0到255,你就需要 256 个数来显示上面的直方图。但是,如果你不需

    2024年02月13日
    浏览(75)
  • 我在Vscode学OpenCV 图像处理五(直方图处理)

    直方图是一种统计图,显示了图像中每个灰度级别(或颜色通道)的像素数量。通过分析图像的直方图,可以获得关于图像对比度、亮度和颜色分布等方面的重要信息。 了解图像的对比度、亮度和色彩分布等信息。你可以使用OpenCV中的函数来计算和绘制图像的直方图,从而进

    2024年01月21日
    浏览(77)
  • Python Opencv实践 - 图像直方图自适应均衡化

       

    2024年02月11日
    浏览(46)
  • C#使用OpenCv(OpenCVSharp)图像直方图均衡化处理实例

    本文实例演示C#语言中如何使用OpenCv(OpenCVSharp)对图像进行直方图均衡化处理。 直方图均衡化原理 直方图均衡化(Histogram Equalization)是一种常用的图像增强技术,用于改善图像的对比度和亮度分布。它通过重新分配图像灰度级的像素值,使得图像的直方图在灰度范围内更加

    2024年02月07日
    浏览(97)
  • 【OpenCV学习笔记30】- OpenCV 中的直方图 - 直方图 - 4:直方图反投影

    这是对于 OpenCV 官方文档中 图像处理 的学习笔记。学习笔记中会记录官方给出的例子,也会给出自己根据官方的例子完成的更改代码,同样彩蛋的实现也会结合多个知识点一起实现一些小功能,来帮助我们对学会的知识点进行结合应用。 如果有喜欢我笔记的请麻烦帮我关注

    2024年03月26日
    浏览(55)
  • Opencv4基于C++基础入门笔记:图像 颜色 事件响应 图形 视频 直方图 Opencv4基于C++的 实时人脸监测

      效果图 ◕‿◕:opencv人脸识别效果图(请叫我真爱粉)✌✌✌先看一下效果图勾起你的兴趣!  文章目录: 一:环境配置搭建 二:图像 1.图像读取与显示 main.cpp  运行结果 2.图像色彩空间转换 2.1 换色彩  test.h  test.cpp main.cpp    运行结果 2.2 照片换背景 test.h        test.

    2024年02月10日
    浏览(57)
  • Opencv4基于C++基础入门笔记:图像 颜色 事件响应 图形 视频 直方图 Opencv4基于C++的 实时人脸检测

      效果图 ◕‿◕:opencv人脸识别效果图(请叫我真爱粉)✌✌✌先看一下效果图勾起你的兴趣!  文章目录: 一:环境配置搭建 二:图像 1.图像读取与显示 main.cpp  运行结果 2.图像色彩空间转换 2.1 换色彩  test.h  test.cpp main.cpp    运行结果 2.2 照片换背景 test.h        test.

    2024年02月13日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包