zoukankan      html  css  js  c++  java
  • 直方图计算

    直方图

    • 直方图是对数据的集合 统计 ,并将统计结果分布于一系列预定义的 bins 中。

    • 这里的 数据 不仅仅指的是灰度值 , 统计数据可能是任何能有效描述图像的特征。

    • 先看一个例子吧。 假设有一个矩阵包含一张图像的信息 (灰度值 0-255):

     

     

    直方图对比可查看:直方图对比

    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    #include <iostream>
    #include <stdio.h>
    
    using namespace std;
    using namespace cv;
    
    /** @函数 main */
    int main(int argc, char** argv)
    {
        Mat src, dst;
    
        /// 装载图像
        src = imread(argv[1], 1);
    
        if (!src.data)
        {
            return -1;
        }
    
        /// 分割成3个单通道图像 ( R, G 和 B )
        vector<Mat> rgb_planes;
        split(src, rgb_planes);
    
        /// 设定bin数目
        int histSize = 255;
    
        /// 设定取值范围 ( R,G,B) )
        float range[] = { 0, 255 };
        const float* histRange = { range };
    
        bool uniform = true; bool accumulate = false;
    
        Mat r_hist, g_hist, b_hist;
    
        /// 计算直方图:
        calcHist(&rgb_planes[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate);
        calcHist(&rgb_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate);
        calcHist(&rgb_planes[2], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate);
    
        // 创建直方图画布
        int hist_w = 400; int hist_h = 400;
        int bin_w = cvRound((double)hist_w / histSize);
    
        Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0, 0));
    
        /// 将直方图归一化到范围 [ 0, histImage.rows ]
        normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
        normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
        normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
    
        /// 在直方图画布上画出直方图
        for (int i = 1; i < histSize; i++)
        {
            line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))),
                Point(bin_w*(i), hist_h - cvRound(r_hist.at<float>(i))),
                Scalar(0, 0, 255), 2, 8, 0);
            line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))),
                Point(bin_w*(i), hist_h - cvRound(g_hist.at<float>(i))),
                Scalar(0, 255, 0), 2, 8, 0);
            line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),
                Point(bin_w*(i), hist_h - cvRound(b_hist.at<float>(i))),
                Scalar(255, 0, 0), 2, 8, 0);
        }
    
        /// 显示直方图
        namedWindow("calcHist Demo", CV_WINDOW_AUTOSIZE);
        imshow("calcHist Demo", histImage);
    
        waitKey(0);
    
        return 0;
    
    }

    上面代码计算一幅图像的直方图!

    最重要的代码:

    OpenCV函数 calcHist 计算直方图:

    /// 计算直方图:
    calcHist( &rgb_planes[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate );
    calcHist( &rgb_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate );
    calcHist( &rgb_planes[2], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate );
    

    参数说明如下:

    • &rgb_planes[0]: 输入数组(或数组集)
    • 1: 输入数组的个数 (这里我们使用了一个单通道图像,我们也可以输入数组集 )
    • 0: 需要统计的通道 (dim)索引 ,这里我们只是统计了灰度 (且每个数组都是单通道)所以只要写 0 就行了。
    • Mat(): 掩码( 0 表示忽略该像素), 如果未定义,则不使用掩码
    • r_hist: 储存直方图的矩阵
    • 1: 直方图维数
    • histSize: 每个维度的bin数目
    • histRange: 每个维度的取值范围
    • uniform 和 accumulate: bin大小相同,清楚直方图痕迹
  • 相关阅读:
    P2015 二叉苹果树(树形DP)
    Treats for the Cows (区间DP)
    You Are the One(区间DP 好题)
    Palindrome subsequence (区间DP)
    Cutting Sticks(区间DP)
    L2-013 红色警报 (dfs判断图连通性)
    L2-001 紧急救援 (dijkstra+dfs回溯路径)
    多线程 -- JMM、volatile关键字、内存屏障、happens-before原则、缓存一致性
    多线程 -- 各种锁的概念
    Spring Boot 学习笔记(十六)启动原理、运行流程、自动配置原理
  • 原文地址:https://www.cnblogs.com/fcfc940503/p/11308768.html
Copyright © 2011-2022 走看看