zoukankan      html  css  js  c++  java
  • 【OpenCV】直方图

    今天写直方图,学了几个相关函数

    1. mixChannels  

    void mixChannels(const Mat* src, int nsrc, Mat* dst, int ndst, const int* fromTo, size_t npairs)

    功能: 把 src 中指定的若干通道 复制到 dst中

    src: 输入图像, 可以多张

    nsrc: 有多少张输入图像

    dst: 输出图像,可以多张

    ndst: 有多少张输出图像

    fromTo: {0 , 1, 1, 2, 2, 0} 这样偶数个数的数组, 表示把输入图像的第0通道复制到输出图像的第1通道, 把输入图像的第1通道复制到输出图像的第2通道, 把输入图像的第2通道复制到输出图像的第0通道。

    nparis:表示有fromTo中有多少对, 对{0 , 1, 1, 2, 2, 0}来说,nparis = 3;

    应用例子: 来源http://www.opencv.org.cn/opencvdoc/2.3.2/html/modules/core/doc/operations_on_arrays.html?highlight=mixchannels#void mixChannels(const Mat* src, int nsrc, Mat* dst, int ndst, const int* fromTo, size_t npairs)

    In the example below, the code splits a 4-channel RGBA image into a 3-channel BGR (with R and B channels swapped) and a separate alpha-channel image:

    Mat rgba( 100, 100, CV_8UC4, Scalar(1,2,3,4) );
    Mat bgr( rgba.rows, rgba.cols, CV_8UC3 );
    Mat alpha( rgba.rows, rgba.cols, CV_8UC1 );
    
    // forming an array of matrices is a quite efficient operation,
    // because the matrix data is not copied, only the headers
    Mat out[] = { bgr, alpha };
    // rgba[0] -> bgr[2], rgba[1] -> bgr[1],
    // rgba[2] -> bgr[0], rgba[3] -> alpha[0]
    int from_to[] = { 0,2, 1,1, 2,0, 3,3 };
    mixChannels( &rgba, 1, out, 2, from_to, 4 );

    2. cvRound

    int cvRound(double value)

    功能:返回与value最接近的整数

    3. createTrackbar

    int cvCreateTrackbar(const char* trackbarName, const char* windowName, int* value, int count, CvTrackbarCallback onChange)

    功能:创建一个滑动条。

    trackbarName: 滑动条名字

    windowname: 滑动条父窗口的名字,滑动条会显示在父窗口上

    value: 滑动条的默认初始值

    count: 滑动条在最大位置时对应的数值, 最小值总是0

    onChange: 滑动条的回调函数, 都是 void Foo(int, void*); 的形式, 其第一个参数是滑动条对应的数值, 第二个参数是传递用户信息的,可以避免使用全局变量

    4. calcHist

    void calcHist(const Mat* arrays, int narrays, const int* channels, InputArray mask, OutputArrayhist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false )

    功能:计算直方图

    arrays: 输入的图像,可以不只一张

    narrays: 输入图像的个数

    channels: 输入图像中用来统计直方图的通道 如果有三张三通道图,则第一张图的三个通道分别是 0, 1, 2, 第二张图的三个通道分别是3, 4, 5, 第三张图的三个通道分别是 6, 7, 8.

    mask: 若非空, 则只有mask中不为0的部分会被用来统计直方图

    hist: 输出直方图

    dims: 输出直方图的维数, 最大不能超过32

    histSize: 每个维度下直方图被分为多少个区间

    ranges: 每个区间的范围, 如果uniform = true 则每个区间会在给定的范围内均匀的选取。 如ranges = {0, 180}, histSize = 4, uniform = true, 则每个区间的范围是[0, 45] [45, 90][90, 135][135, 180];  如果uniform = false 则每个区间的范围都要给出如: ranges = {0, 20, 60, 120, 180}, 区间范围是[0, 20][20, 60][60, 120][120, 180]

    uniform: 区间是否均匀

    accumulate: 如果是true,hist在使用中不会被清零,可以使多个图的直方图叠加在一起。

    下面的例子用到了上面的函数,用来计算一幅图的直方图和反向投影图。

    来源:http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/histograms/back_projection/back_projection.html?highlight=histogram

    #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/highgui/highgui.hpp"
    
    #include <iostream>
    
    using namespace cv;
    using namespace std;
    
     Mat hsv; Mat hue;
    int bins = 25;
    
    void Hist_and_Backproj(int, void*);
    
    int main()
    {
        IplImage *pimg = cvLoadImage("E:\picture\013.jpg");
        Mat src(pimg);
        //src = imread("F:\competition\label_results\dongnanmen_1_1280x720_30_R1_0000001.jpg", 1);
        //imshow("test", src);
        cvtColor(src, hsv, CV_BGR2HSV);
    
        //分离Hue通道
        hue.create(hsv.size(), hsv.depth());
        int ch[] = {0, 0};
        mixChannels(&hsv, 1, &hue, 1, ch, 1);
    
        //创建Trackbar 来输入bin的数目
        char* window_image = "Source image";
        namedWindow(window_image, CV_WINDOW_AUTOSIZE);
        createTrackbar("* Hue bins: ", window_image, &bins, 180, Hist_and_Backproj);
        Hist_and_Backproj(0, 0);
    
        imshow(window_image, src);
    
        waitKey(0);
        return 0;
    }
    
    //Trackbar事件的回调函数
    void Hist_and_Backproj(int, void*)
    {
        MatND hist;
        int histSize = MAX(bins, 2);
        float hue_range[] = {0, 180};
        const float* ranges = {hue_range};
    
        //计算直方图并归一化
        calcHist(&hue, 1, 0, Mat(), hist, 1, &histSize, &ranges, true, false);
        normalize(hist, hist, 0, 255, NORM_MINMAX, -1, Mat());
    
        //计算反向投影
        MatND backproj;
        calcBackProject(&hue, 1, 0, hist, backproj, &ranges, 1, true);
    
        //显示反向投影图
        imshow("BackProj", backproj);
    
        //显示直方图
        int w = 400; int h = 400;
        int bin_w = cvRound((double)w / histSize);
        Mat histImg = Mat::zeros(w, h, CV_8UC3);
    
        for(int i = 0; i < bins; i++)
        {
            rectangle(histImg, Point(i * bin_w, h), Point((i + 1) * bin_w, h - cvRound(hist.at<float>(i) * h / 255.0)), Scalar(0, 0, 255), -1);
        }
        imshow("Histogram", histImg);
    }
  • 相关阅读:
    easyui datagrid 本地json数据 实现删除
    Kindeditor单独调用多图上传
    Kindeditor单独调用单图上传增加预览
    HTML <frameset> 标签
    easyui datagrid 获取行数据某个字段
    easyui datagrid 表格中操作栏 按钮图标不显示
    web安全之XSS跨站脚步攻击
    兼容低版本JS的Array.map方法
    关于wince串口接收数据异常
    VC中控制台程序和基于对话框的程序之间的区别
  • 原文地址:https://www.cnblogs.com/dplearning/p/3845153.html
Copyright © 2011-2022 走看看