• c++视觉处理----绘制直方图,H—S直方图,二维H—S直方图,RGB三色直方图


    直方图cv::calcHist()

    cv::calcHist()OpenCV 中用于计算直方图的函数。直方图是一种用于可视化图像亮度或颜色分布的工具。这函数通常应用于灰度图像或彩色图像的各个通道。以下是 cv::calcHist() 函数的基本语法和参数:

    void cv::calcHist(
        const cv::Mat* images, // 输入图像的数组
        int nimages,           // 输入图像的数量
        const int* channels,   // 通道索引数组(可以为空)
        const cv::InputArray& mask, // 掩模图像(可以为空)
        cv::OutputArray& hist,      // 输出的直方图
        int dims,                 // 直方图的维数
        const int* histSize,      // 直方图的尺寸数组
        const float* ranges[],    // 直方图范围数组
        bool uniform = true,      // 直方图是否均匀分布
        bool accumulate = false   // 是否累积直方图
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    以下是参数的说明:

    • images:输入图像的数组,可以是一个或多个图像。
    • nimages:输入图像的数量,通常为1。
    • channels:通道索引数组,指定要计算直方图的通道。对于灰度图像,通常为0。对于彩色图像,通道索引可以是{0, 1, 2},分别代表蓝色、绿色和红色通道。
    • mask:可选的掩模图像,用于限制计算直方图的区域。可以为空。
    • hist:输出的直方图。
    • dims:直方图的维数。通常为1。
    • histSize:直方图的尺寸数组,表示直方图的柱数。
    • ranges:直方图范围数组,指定直方图的范围。通常为{0, 256},表示像素值的范围。
    • uniform:指定是否将直方图均匀分布,如果为true,每个直方柱的宽度相同。
    • accumulate:指定是否累积直方图,如果为true,直方图将被累积。

    cv::calcHist() 函数用于计算直方图后,你可以进一步分析或可视化直方图数据。这对于图像处理、分析和计算机视觉任务非常有用。

    以下是一个更完整的 cv::calcHist() 函数的示例,它将计算一幅图像的直方图并绘制出来。这个示例假定你已经读取了一幅图像,并且使用灰度图像计算直方图:

    #include 
    #include 
    
    int main() {
        // 读取图像
        cv::Mat image = cv::imread("your_image.jpg");
    
        if (image.empty()) {
            std::cerr << "Error: Could not read the image." << std::endl;
            return -1;
        }
    
        // 将图像转换为灰度图像
        cv::Mat gray_image;
        cv::cvtColor(image, gray_image, cv::COLOR_BGR2GRAY);
    
        // 定义直方图的参数
        int histSize = 256; // 直方图中的条柱数量
        float range[] = {0, 256}; // 像素值范围
        const float* histRange = {range};
    
        // 计算直方图
        cv::Mat hist;
        cv::calcHist(&gray_image, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange);
    
        // 创建一个空的直方图图像
        int hist_w = 512;
        int hist_h = 400;
        cv::Mat hist_image(hist_h, hist_w, CV_8UC3, cv::Scalar(0, 0, 0));
    
        // 归一化直方图
        cv::normalize(hist, hist, 0, hist_image.rows, cv::NORM_MINMAX, -1, cv::Mat());
    
        // 绘制直方图
        for (int i = 1; i < histSize; i++) {
            cv::line(hist_image, cv::Point(i - 1, hist_h - cvRound(hist.at<float>(i - 1))),
                     cv::Point(i, hist_h - cvRound(hist.at<float>(i))),
                     cv::Scalar(255, 255, 255), 2, 8, 0);
        }
    
        // 显示原始图像和直方图
        cv::namedWindow("Original Image", cv::WINDOW_AUTOSIZE);
        cv::imshow("Original Image", gray_image);
    
        cv::namedWindow("Histogram", cv::WINDOW_AUTOSIZE);
        cv::imshow("Histogram", hist_image);
    
        cv::waitKey(0);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    这个示例将图像转换为灰度图像,计算其直方图,然后绘制直方图并显示原始图像以及对应的直方图。希望这个示例可以帮助你理解如何使用 cv::calcHist() 函数来计算和可视化图像的直方图。
    在这里插入图片描述

    绘制H—S直方图

    #include 
    
    int main() {
        // 读取图像
        cv::Mat image = cv::imread("1.jpg");
    
        if (image.empty()) {
            std::cerr << "Error: Could not read the image." << std::endl;
            return -1;
        }
    
        // 将图像转换为HSV颜色空间
        cv::Mat hsv_image;
        cv::cvtColor(image, hsv_image, cv::COLOR_BGR2HSV);
    
        // 分割H和S通道
        std::vector<cv::Mat> channels;
        cv::split(hsv_image, channels);
    
        // 定义直方图的参数
        int histSize = 256; // 直方图中的条柱数量
        float hRange[] = { 0, 256 }; // 色相通道的像素值范围
        const float* hHistRange = { hRange };
        float sRange[] = { 0, 256 }; // 饱和度通道的像素值范围
        const float* sHistRange = { sRange };
    
        // 计算H和S通道的直方图
        cv::Mat h_hist, s_hist;
        cv::calcHist(&channels[0], 1, 0, cv::Mat(), h_hist, 1, &histSize, &hHistRange);
        cv::calcHist(&channels[1], 1, 0, cv::Mat(), s_hist, 1, &histSize, &sHistRange);
    
        // 归一化直方图
        cv::normalize(h_hist, h_hist, 0, 255, cv::NORM_MINMAX, -1, cv::Mat());
        cv::normalize(s_hist, s_hist, 0, 255, cv::NORM_MINMAX, -1, cv::Mat());
    
        // 创建一个直方图图像
        int hist_w = 512;
        int hist_h = 400;
        cv::Mat hist_image(hist_h, hist_w, CV_8UC3, cv::Scalar(0, 0, 0));
    
        // 绘制H通道直方图
        for (int i = 1; i < histSize; i++) {
            cv::line(hist_image, cv::Point(i - 1, hist_h - cvRound(h_hist.at<float>(i - 1))),
                cv::Point(i, hist_h - cvRound(h_hist.at<float>(i))),
                cv::Scalar(0, 0, 255), 2, 8, 0);
        }
    
        // 绘制S通道直方图
        for (int i = 1; i < histSize; i++) {
            cv::line(hist_image, cv::Point(i - 1, hist_h - cvRound(s_hist.at<float>(i - 1))),
                cv::Point(i, hist_h - cvRound(s_hist.at<float>(i))),
                cv::Scalar(0, 255, 0), 2, 8, 0);
        }
    
        // 显示图像和H-S直方图
        cv::imshow("mage", image);
        cv::imshow("H-S Histogram", hist_image);
    
        cv::waitKey(0);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    在这里插入图片描述

    绘制二维H—S直方图

    #include 
    
    int main() {
        // 读取图像
        cv::Mat image = cv::imread("1.jpg");
    
        if (image.empty()) {
            std::cerr << "Error: Could not read the image." << std::endl;
            return -1;
        }
    
        // 将图像转换为HSV颜色空间
        cv::Mat hsv_image;
        cv::cvtColor(image, hsv_image, cv::COLOR_BGR2HSV);
    
        // 定义直方图的参数
        int h_bins = 30; // 色相通道的柱数
        int s_bins = 32; // 饱和度通道的柱数
        int histSize[] = {h_bins, s_bins};
    
        float h_range[] = {0, 180}; // 色相通道的范围
        float s_range[] = {0, 256}; // 饱和度通道的范围
        const float* ranges[] = {h_range, s_range};
    
        // 计算H-S直方图
        cv::MatND hist;
        int channels[] = {0, 1}; // 色相和饱和度通道
        cv::calcHist(&hsv_image, 1, channels, cv::Mat(), hist, 2, histSize, ranges, true, false);
    
        // 归一化直方图
        cv::normalize(hist, hist, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
    
        // 创建一个H-S直方图图像
        int hist_w = 512;
        int hist_h = 512;
        cv::Mat hist_image(hist_h, hist_w, CV_8UC3, cv::Scalar(0, 0, 0));
    
        // 绘制直方图
        for (int h = 0; h < h_bins; h++) {
            for (int s = 0; s < s_bins; s++) {
                float bin_val = hist.at<float>(h, s);
                int intensity = cvRound(bin_val * 255);
                cv::rectangle(hist_image, cv::Point(h * (hist_w / h_bins), s * (hist_h / s_bins)),
                              cv::Point((h + 1) * (hist_w / h_bins), (s + 1) * (hist_h / s_bins)),
                              cv::Scalar(intensity, intensity, intensity), -1);
            }
        }
    
        // 显示原始图像和H-S直方图
        cv::imshow("Image", image);
        cv::imshow("H-S Histogram", hist_image);
    
        cv::waitKey(0);
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    在这里插入图片描述

    绘制RGB三色直方图

    #include 
    
    int main() {
        // 读取图像
        cv::Mat image = cv::imread("1.jpg");
    
        if (image.empty()) {
            std::cerr << "Error: Could not read the image." << std::endl;
            return -1;
        }
    
        // 定义直方图的参数
        int histSize = 256; // 直方图中的条柱数量
        float range[] = { 0, 256 }; // 像素值范围
        const float* histRange = { range };
    
        // 分割RGB通道
        std::vector<cv::Mat> channels;
        cv::split(image, channels);
    
        // 计算红色通道的直方图
        cv::Mat red_hist;
        cv::calcHist(&channels[2], 1, 0, cv::Mat(), red_hist, 1, &histSize, &histRange);
    
        // 计算绿色通道的直方图
        cv::Mat green_hist;
        cv::calcHist(&channels[1], 1, 0, cv::Mat(), green_hist, 1, &histSize, &histRange);
    
        // 计算蓝色通道的直方图
        cv::Mat blue_hist;
        cv::calcHist(&channels[0], 1, 0, cv::Mat(), blue_hist, 1, &histSize, &histRange);
    
        // 归一化直方图
        cv::normalize(red_hist, red_hist, 0, 255, cv::NORM_MINMAX, -1, cv::Mat());
        cv::normalize(green_hist, green_hist, 0, 255, cv::NORM_MINMAX, -1, cv::Mat());
        cv::normalize(blue_hist, blue_hist, 0, 255, cv::NORM_MINMAX, -1, cv::Mat());
    
        // 创建一个直方图图像
        int hist_w = 512;
        int hist_h = 400;
        cv::Mat hist_image(hist_h, hist_w, CV_8UC3, cv::Scalar(0, 0, 0));
    
        // 绘制红色通道直方图
        for (int i = 1; i < histSize; i++) {
            cv::line(hist_image, cv::Point(i - 1, hist_h - cvRound(red_hist.at<float>(i - 1))),
                cv::Point(i, hist_h - cvRound(red_hist.at<float>(i))),
                cv::Scalar(0, 0, 255), 2, 8, 0);
        }
    
        // 绘制绿色通道直方图
        for (int i = 1; i < histSize; i++) {
            cv::line(hist_image, cv::Point(i - 1, hist_h - cvRound(green_hist.at<float>(i - 1))),
                cv::Point(i, hist_h - cvRound(green_hist.at<float>(i))),
                cv::Scalar(0, 255, 0), 2, 8, 0);
        }
    
        // 绘制蓝色通道直方图
        for (int i = 1; i < histSize; i++) {
            cv::line(hist_image, cv::Point(i - 1, hist_h - cvRound(blue_hist.at<float>(i - 1))),
                cv::Point(i, hist_h - cvRound(blue_hist.at<float>(i))),
                cv::Scalar(255, 0, 0), 2, 8, 0);
        }
    
        // 显示原始图像和RGB三色直方图
        cv::imshow("mage", image);
        cv::imshow("RGB Histogram", hist_image);
    
        cv::waitKey(0);
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    在这里插入图片描述

  • 相关阅读:
    ES6模块化规范
    Java-程序控制语句
    5月刚刚阿里面软件测试岗回来,3+1面任职阿里P7,年薪28*15薪
    凉鞋的 Godot 笔记 104. 测试所涉及的窗口
    【WSL/WSL2-Ubuntu】突破界限:不使用服务器在一台Windows搭建Nginx+FastDFS
    Java客户端_zkclient库操作Zookeeper
    【操作系统】孤儿/僵尸/守护进程
    在线BLOG网|基于springboot框架+ Mysql+Java+JSP技术的在线BLOG网设计与实现(可运行源码+数据库+设计文档)
    Git 客户端基本使用及新手常见问题
    利用福禄克DSX-5000 CH测试串扰
  • 原文地址:https://blog.csdn.net/qq_46107892/article/details/133789594