C++ 中怎么利用OpenCV实现直方图计算

发布时间:2021-07-02 17:46:29 作者:Leah
阅读:834
C++开发者专用服务器,限时0元免费领! 查看>>

C++ 中怎么利用OpenCV实现直方图计算

在图像处理中,直方图是一种非常重要的工具,用于表示图像中像素强度的分布情况。通过直方图,我们可以直观地了解图像的亮度、对比度等信息。OpenCV 是一个功能强大的计算机视觉库,提供了丰富的函数来处理图像和计算直方图。本文将介绍如何在 C++ 中使用 OpenCV 实现直方图的计算。

1. 准备工作

在开始之前,确保你已经安装了 OpenCV 库,并且配置好了开发环境。如果你还没有安装 OpenCV,可以参考官方文档进行安装。

2. 加载图像

首先,我们需要加载一张图像。OpenCV 提供了 cv::imread 函数来读取图像文件。以下是一个简单的代码示例:

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

int main() {
    // 读取图像
    cv::Mat image = cv::imread("example.jpg", cv::IMREAD_COLOR);

    if (image.empty()) {
        std::cerr << "Could not open or find the image!" << std::endl;
        return -1;
    }

    // 显示图像
    cv::imshow("Original Image", image);
    cv::waitKey(0);

    return 0;
}

在这个示例中,我们使用 cv::imread 函数读取了一张名为 example.jpg 的图像,并使用 cv::imshow 函数显示图像。

3. 计算直方图

OpenCV 提供了 cv::calcHist 函数来计算图像的直方图。该函数可以计算单通道或多通道图像的直方图。以下是一个计算灰度图像直方图的示例:

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

int main() {
    // 读取图像
    cv::Mat image = cv::imread("example.jpg", cv::IMREAD_GRAYSCALE);

    if (image.empty()) {
        std::cerr << "Could not open or find the image!" << std::endl;
        return -1;
    }

    // 定义直方图参数
    int histSize = 256; // 直方图的 bin 数量
    float range[] = {0, 256}; // 像素值范围
    const float* histRange = {range};
    bool uniform = true, accumulate = false;

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

    // 显示直方图
    int hist_w = 512, hist_h = 400;
    int bin_w = cvRound((double) hist_w / histSize);

    cv::Mat histImage(hist_h, hist_w, CV_8UC3, 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(bin_w * (i - 1), hist_h - cvRound(hist.at<float>(i - 1)),
                 cv::Point(bin_w * (i), hist_h - cvRound(hist.at<float>(i))),
                 cv::Scalar(255, 255, 255), 2, 8, 0);
    }

    // 显示直方图图像
    cv::imshow("Histogram", histImage);
    cv::waitKey(0);

    return 0;
}

在这个示例中,我们首先将图像转换为灰度图像,然后使用 cv::calcHist 函数计算直方图。直方图的 bin 数量设置为 256,表示每个像素强度值(0-255)都有一个对应的 bin。最后,我们使用 cv::line 函数绘制直方图,并显示出来。

4. 计算彩色图像的直方图

对于彩色图像,我们可以分别计算每个通道的直方图。以下是一个计算彩色图像直方图的示例:

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

int main() {
    // 读取图像
    cv::Mat image = cv::imread("example.jpg", cv::IMREAD_COLOR);

    if (image.empty()) {
        std::cerr << "Could not open or find the image!" << std::endl;
        return -1;
    }

    // 分离通道
    std::vector<cv::Mat> bgr_planes;
    cv::split(image, bgr_planes);

    // 定义直方图参数
    int histSize = 256;
    float range[] = {0, 256};
    const float* histRange = {range};
    bool uniform = true, accumulate = false;

    // 计算每个通道的直方图
    cv::Mat b_hist, g_hist, r_hist;
    cv::calcHist(&bgr_planes[0], 1, 0, cv::Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate);
    cv::calcHist(&bgr_planes[1], 1, 0, cv::Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate);
    cv::calcHist(&bgr_planes[2], 1, 0, cv::Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate);

    // 显示直方图
    int hist_w = 512, hist_h = 400;
    int bin_w = cvRound((double) hist_w / histSize);

    cv::Mat histImage(hist_h, hist_w, CV_8UC3, cv::Scalar(0, 0, 0));

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

    // 绘制直方图
    for (int i = 1; i < histSize; i++) {
        cv::line(histImage, cv::Point(bin_w * (i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),
                 cv::Point(bin_w * (i), hist_h - cvRound(b_hist.at<float>(i))),
                 cv::Scalar(255, 0, 0), 2, 8, 0);
        cv::line(histImage, cv::Point(bin_w * (i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))),
                 cv::Point(bin_w * (i), hist_h - cvRound(g_hist.at<float>(i))),
                 cv::Scalar(0, 255, 0), 2, 8, 0);
        cv::line(histImage, cv::Point(bin_w * (i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))),
                 cv::Point(bin_w * (i), hist_h - cvRound(r_hist.at<float>(i))),
                 cv::Scalar(0, 0, 255), 2, 8, 0);
    }

    // 显示直方图图像
    cv::imshow("Histogram", histImage);
    cv::waitKey(0);

    return 0;
}

在这个示例中,我们首先使用 cv::split 函数将彩色图像分离为三个通道(B、G、R),然后分别计算每个通道的直方图。最后,我们使用不同的颜色绘制每个通道的直方图,并显示出来。

5. 总结

通过本文的介绍,我们学习了如何在 C++ 中使用 OpenCV 计算图像的直方图。无论是灰度图像还是彩色图像,OpenCV 都提供了强大的函数来帮助我们完成这些任务。直方图是图像处理中非常重要的工具,掌握它的计算方法对于进一步学习和应用图像处理技术非常有帮助。希望本文对你有所帮助!

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

推荐阅读:
  1. opencv3/C++ 直方图反向投影实例
  2. opencv3/C++ HOG特征提取方式

开发者交流群:

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

原文链接:https://my.oschina.net/u/4582134/blog/4582661

c++ opencv

上一篇:Go语言的错误处理方式

下一篇:怎么用Git实现自动化部署你的项目

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》
开发者交流群×