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

本文详细介绍了OpenCV中的cv::calcHist()函数,用于计算直方图,包括其参数解释、在图像处理中的应用,以及如何使用该函数计算和可视化灰度图像、彩色图像和不同通道的直方图。提供了实际代码示例以帮助理解和实践。
摘要由CSDN通过智能技术生成

直方图: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   // 是否累积直方图
);

以下是参数的说明:

  • 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 <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

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

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

绘制H—S直方图

#include <opencv2/opencv.hpp>

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

在这里插入图片描述

绘制二维H—S直方图

#include <opencv2/opencv.hpp>

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

在这里插入图片描述

绘制RGB三色直方图

#include <opencv2/opencv.hpp>

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

在这里插入图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枭玉龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值