溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++ 中怎么利用OpenCV實現直方圖計算

發布時間:2021-07-02 17:46:29 來源:億速云 閱讀:878 作者:Leah 欄目:大數據

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 都提供了強大的函數來幫助我們完成這些任務。直方圖是圖像處理中非常重要的工具,掌握它的計算方法對于進一步學習和應用圖像處理技術非常有幫助。希望本文對你有所幫助!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女