zoukankan      html  css  js  c++  java
  • OpenCV手工实现灰度及RGB直方图

    手工实现灰度及RGB直方图 !库

    1. 灰度图像直方图

    算法

    1. 图片灰度化;

    2. 遍历Mat,统计各灰度级的像素个数;

    3. 根据opencv画点线函数,绘制坐标轴及像素分布图

    源码(编译环境:VS2017+OpenCV) 补充:三通道直方图(即RGB彩色图象直方图在后面)

     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 #include <opencv2/opencv.hpp>
     5 #include <opencv2/imgproc/imgproc.hpp>
     6 #include <opencv2/core/core.hpp>
     7 #include <opencv2/highgui/highgui.hpp>
     8 using namespace cv;
     9 using namespace std;
    10 //直方图绘制函数,参数vector<int> nums 是灰度图片256级灰度的像素个数
    11 void drawHist(vector<int> nums)
    12 {
    13     Mat hist = Mat::zeros(600, 800, CV_8UC3);
    14     auto Max = max_element(nums.begin(), nums.end());//max迭代器类型,最大数目
    15     putText(hist, "Histogram", Point(150, 100), FONT_HERSHEY_DUPLEX, 1, Scalar(255, 255, 255));
    16     //*********绘制坐标系************//
    17     Point o = Point(100, 550);
    18     Point x = Point(700, 550);
    19     Point y = Point(100, 150);
    20     //x轴
    21     line(hist, o, x, Scalar(255, 255, 255), 2, 8, 0);
    22     //y轴
    23     line(hist, o, y, Scalar(255, 255, 255), 2, 8, 0);
    24 
    25     //********绘制灰度曲线***********//
    26     Point pts[256];
    27     //生成坐标点
    28     for (int i = 0; i < 256; i++)
    29     {
    30         pts[i].x = i * 2 + 100;
    31         pts[i].y = 550 - int(nums[i]*(300.0/(*Max)));//归一化到[0, 300]
    32         //显示横坐标
    33         if ((i + 1) % 16 == 0)
    34         {
    35             string num = format("%d", i + 1);
    36             putText(hist, num, Point(pts[i].x, 570), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255, 255, 255));
    37         }
    38     }
    39     //绘制线
    40     for (int i = 1; i < 256; i++)
    41     {
    42         line(hist, pts[i - 1], pts[i], Scalar(0, 255, 0), 2);
    43     }
    44     //显示图像
    45     imshow("直方图" ,hist);
    46 }
    47 //计算直方图,统计各灰度级像素个数
    48 void calHist(const string img)
    49 {
    50     Mat src, grey;
    51     //读取图象
    52     src = imread(img);
    53     if (!src.data)
    54     {
    55         cout << "Image: " + img + " 读取失败" << endl;
    56         return;
    57     }
    58     //先转为灰度图
    59     cvtColor(src, grey, COLOR_BGR2GRAY);
    60     imshow("灰度图", grey);
    61     //计算各灰度级像素个数
    62     vector<int> nums(256);
    63     for (int i = 0; i < grey.rows; i++)
    64     {
    65         uchar* p = grey.ptr<uchar>(i);
    66         for (int j = 0; j < grey.cols; j++)
    67         {
    68             nums[p[j]]++;
    69         }
    70     }
    71     drawHist(nums);
    72 }
    73 
    74 int main()
    75 {
    76     string img = "D:\trashBox\testIMG\lena.bmp";
    77     calHist(img);
    78     
    79     waitKey(0);
    80     return 0;
    81 }

    效果图

    直方图hist

     2. RGB彩色图象直方图

    源码

    #include <iostream>
    #include <stdlib.h>
    #include <string>
    #include <algorithm>
    #include <opencv2/opencv.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/video.hpp>
    using namespace cv;
    using namespace std;
    
    //单通道图片直方图绘制
    void drawHist(vector<int> nums)
    {
        Mat hist = Mat::zeros(600, 800, CV_8UC3);
        auto Max = max_element(nums.begin(), nums.end());//max迭代器类型,最大数目
        putText(hist, "Histogram", Point(150, 100), FONT_HERSHEY_DUPLEX, 1, Scalar(255, 255, 255));
        //*********绘制坐标系************//
        Point o = Point(100, 550);
        Point x = Point(700, 550);
        Point y = Point(100, 150);
        //x轴
        line(hist, o, x, Scalar(255, 255, 255), 2, 8, 0);
        //y轴
        line(hist, o, y, Scalar(255, 255, 255), 2, 8, 0);
    
        //********绘制灰度曲线***********//
        Point pts[256];
        //生成坐标点
        for (int i = 0; i < 256; i++)
        {
            pts[i].x = i * 2 + 100;
            pts[i].y = 550 - int(nums[i]*(300.0/(*Max)));//归一化到[0, 300]
            //显示横坐标
            if ((i + 1) % 16 == 0)
            {
                string num = format("%d", i + 1);
                putText(hist, num, Point(pts[i].x, 570), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255, 255, 255));
            }
        }
        //绘制线
        for (int i = 1; i < 256; i++)
        {
            line(hist, pts[i - 1], pts[i], Scalar(0, 255, 0), 2);
        }
        //显示图像
        imshow("直方图" ,hist);
    }
    
    //三通道图片直方图绘制
    void drawHist(vector<int> &r, vector<int> &g, vector<int> &b)
    {
        Mat hist = Mat::zeros(600, 800, CV_8UC3);
        putText(hist, "Histogram", Point(150, 100), FONT_HERSHEY_DUPLEX, 1, Scalar(255, 255, 255));
        //*********绘制坐标系************//
        Point o = Point(100, 550);
        Point x = Point(700, 550);
        Point y = Point(100, 150);
        //x轴
        line(hist, o, x, Scalar(255, 255, 255), 2, 8, 0);
        //y轴
        line(hist, o, y, Scalar(255, 255, 255), 2, 8, 0);
    
        //********绘制灰度曲线***********//
        auto Max_r = max_element(r.begin(), r.end());
        auto Max_g = max_element(g.begin(), g.end());
        auto Max_b = max_element(b.begin(), b.end());
        Point pts[3][256];
        //生成坐标点
        for (int i = 0; i < 256; i++)
        {
            pts[0][i].x = i * 2 + 100;
            pts[0][i].y = 550 - int(r[i] * (300.0 / (*Max_r)));//归一化到[0, 300]
            pts[1][i].x = i * 2 + 100;
            pts[1][i].y = 550 - int(g[i] * (300.0 / (*Max_g)));//归一化到[0, 300]
            pts[2][i].x = i * 2 + 100;
            pts[2][i].y = 550 - int(b[i] * (300.0 / (*Max_b)));//归一化到[0, 300]
            //显示横坐标
            if ((i + 1) % 16 == 0)
            {
                string num = format("%d", i + 1);
                putText(hist, num, Point(pts[0][i].x, 570), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255, 255, 255));
            }
        }
        //绘制线
        for (int i = 1; i < 256; i++)
        {
            line(hist, pts[0][i - 1], pts[0][i], Scalar(255, 0, 0), 2);
            line(hist, pts[1][i - 1], pts[1][i], Scalar(0, 255, 0), 2);
            line(hist, pts[2][i - 1], pts[2][i], Scalar(0, 0, 255), 2);
        }
        //显示图像
        imshow("直方图", hist);
    }
    
    //灰度直方图计算
    void calHist(const string img)
    {
        Mat src, grey;
        //读取图象
        src = imread(img);
        if (!src.data)
        {
            cout << "Image: " + img + " 读取失败" << endl;
            return;
        }
        //先转为灰度图
        cvtColor(src, grey, COLOR_BGR2GRAY);
        imshow("灰度图", grey);
        //计算各灰度级像素个数
        vector<int> nums(256);
        for (int i = 0; i < grey.rows; i++)
        {
            uchar* p = grey.ptr<uchar>(i);
            for (int j = 0; j < grey.cols; j++)
            {
                nums[p[j]]++;
            }
        }
        drawHist(nums);
    }
    
    //多通道直方图计算
    void calHist(const string img, int pattern)
    {
        Mat src, grey;
        //读取图象
        src = imread(img);
        if (!src.data)
        {
            cout << "Image: " + img + " 读取失败" << endl;
            return;
        }
        imshow("原图像",src);
        //计算各灰度级像素个数
        vector<int> r(256, 0);
        vector<int> g(256, 0);
        vector<int> b(256, 0);
        for (int i = 0; i < src.rows; i++)
        {
            uchar* p = src.ptr<uchar>(i);
            for (int j = 0; j < src.cols; j++)
            {
                r[p[j * 3 + 0]]++;
                g[p[j * 3 + 1]]++;
                b[p[j * 3 + 2]]++;
            }
        }
        drawHist(r, g, b);
    }
    
    int main()
    {
        string img = "D:\trashBox\testIMG\tiger.jpg";
        calHist(img);//计算灰度直方图
        calHist(img, 0);//计算三色直方图
        
        waitKey(0);
        return 0;
    }

    算法

    1. 遍历Mat,统计RGB三通道各灰度级的像素个数;

    2. 根据opencv画点线函数,绘制坐标轴及像素分布图

    效果

     

    三色(三通道)直方图

  • 相关阅读:
    取得system32文件夹下面文件的写入权限
    几个SQL语句(备忘)
    Excel多表合并的宏
    删除系统旧网卡
    Eclipse 迁移到Android studio
    是否使用安全模式启动word
    微信公众平台开发
    delphi安装 Tclientsocket, Tserversocket控件
    win10 Internet Explorer 11 停止工作处理
    java编译出错信息汇总(更新)
  • 原文地址:https://www.cnblogs.com/yocichen/p/10849783.html
Copyright © 2011-2022 走看看