ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【14】opencv直方图

2022-03-26 10:04:03  阅读:195  来源: 互联网

标签:14 int hist opencv 直方图 图像 include Mat


参考:https://blog.csdn.net/zhu_hongji/article/details/81663161

定义:

统计学中,直方图是一种对数据分布情况的图形表示,是一种二维统计图表,他的两个坐标分别是统计样本(图像、视频帧)和样本的某种属性(亮度,像素值,梯度,方向,色彩等等任何特征)。

 

 (一)首先学习直方图的均衡化:

C++ void equalizeHist(InputArray src, OutputArray dst)
//第一个参数,源图像,需为8位单通道图像
//第二个参数,输出图像,尺寸、类型和源图像一致
注意:直方图均衡化就是通过拉伸像素强度分布范围来增强图像对比度的一种方法。

 

 

/*
* 001 对于灰白图像的均衡化
* 
这一段代码实现的是对于图像1维数读取以及
对于黑白图像的效果进行增强,即均衡化
注意:为了方便,我将本来存彩图的mat类型的东西变成了output
*/

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

using namespace std;
using namespace cv;

int main()
{
    int ChannelNumber;
    Mat OriginImage = imread("0003.jpg");
    Mat OutPutImage = Mat(OriginImage.size(), OriginImage.type());
    if (!OriginImage.data)
    {
        cout << "ERROR" << endl;
        return -1;
    }

    cvtColor(OriginImage, OutPutImage, COLOR_BGR2GRAY);
    imshow("origin", OutPutImage);
    ChannelNumber = OutPutImage.channels();
    cout << "这个图像的通道数为" << ChannelNumber << endl;

    equalizeHist(OutPutImage, OriginImage);
    imshow("AFTER", OriginImage);

    waitKey(0);
}

接下来就是三通道的彩色图像了:

注意:这里的三个通道使用split分别对vector构建的mat类型处理,然后令BGR分别设置为mat类型,使用浅拷贝的方式,将分离出来的三个通道拷贝(因而对于RGBMat类型的操作其实也就是对于

三个通道的数组进行修改。

 

 

/*
* 002彩色图像的均衡化
* 主要是运用split函数分离图像,存储入channels的数组里面

*/
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main()
{
    Mat Origin = imread("0003.jpg");
    if (!Origin.data)
    {
        cout << "error" << endl;
        return -1;
    }
    Mat Output_1 = Mat(Origin.size(), Origin.type());
    Mat Course_1 = Mat(Origin.size(), Origin.type());
    imshow("00000",Origin);

    std::vector<cv::Mat> channels;
    split(Origin, channels);
    Mat G, B, R;

    B = channels.at(0);
    G = channels.at(1);
    R = channels.at(2);                                           //因为opencv是按照BGR存储的

    equalizeHist(B, B);
    equalizeHist(G, G);
    equalizeHist(R, R);

    merge(channels, Output_1);
    imshow("output", Output_1);

    waitKey(0);

}

(二)直方图的计算与绘制:

C++ Void calcHist(
            const Mat* images,//输入图像指针
            int images,// 图像数目
            const int* channels,// 通道数
            InputArray mask,// 输入mask,可选,不用
            OutputArray hist,//输出的直方图数据
            int dims,// 维数
            const int* histsize,// 直方图级数
            const float* ranges,// 值域范围
            bool uniform,// true by default
            bool accumulate)// false by defaut
//寻找最值函数
C++ void minMaxLoc(InputArray src, double* minVal, double* maxVal=0, 
                    Point* minLoc=0,Point* maxLoc=0,InputArray mask=noArray())
        //第一个参数:输入单通道阵列
        //第二个参数:返回最小值的指针,若无需返回,此值置为NULL
        //第三个参数:返回最大值的指针,若无需返回,此值置为NULL
        //第四个参数:返回最小位置的指针(二维情况下),若无需返回,此值置为NULL
        //第五个参数:返回最大位置的指针(二维情况下),若无需返回,此值置为NULL
        //第六个参数:用于选择子阵列的可选掩膜

 

//#include<opencv2/opencv.hpp>
//#include<iostream>
//#include<math.h>
//
//using namespace cv;
//using namespace std;
//
//const char* output = "image";
//
//int main(int argc, char* argv)
//{
//    Mat src, dst, dst1;
//    src = imread("0003.jpg");
//    if (!src.data)
//    {
//        printf("could not load image...\n");
//        return -1;
//    }
//    char input[] = "input image";
//    namedWindow(input, WINDOW_FREERATIO);
//    namedWindow(output,WINDOW_FREERATIO);
//    imshow(input, src);
//
//    //步骤一:分通道显示
//    vector<Mat>bgr_planes;
//    split(src, bgr_planes);
//    //split(// 把多通道图像分为多个单通道图像 const Mat &src, //输入图像 Mat* mvbegin)// 输出的通道图像数组
//
//    //步骤二:计算直方图
//    int histsize = 256;
//    float range[] = { 0,256 };
//    const float* histRanges = { range };
//    Mat b_hist, g_hist, r_hist;
//    calcHist(&bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histsize, &histRanges, true, false);
//    calcHist(&bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histsize, &histRanges, true, false);
//    calcHist(&bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histsize, &histRanges, true, false);
//
//
//    //归一化
//    int hist_h = 400;//直方图的图像的高
//    int hist_w = 512; //直方图的图像的宽
//    int bin_w = hist_w / histsize;//直方图的等级
//    Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0, 0));//绘制直方图显示的图像
//    normalize(b_hist, b_hist, 0, hist_h, NORM_MINMAX, -1, Mat());//归一化
//    normalize(g_hist, g_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
//    normalize(r_hist, r_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
//
//    //步骤三:绘制直方图(render histogram chart)
//    for (int i = 1; i < histsize; i++)
//    {
//        //绘制蓝色分量直方图
//        line(histImage, Point((i - 1) * bin_w, hist_h - cvRound(b_hist.at<float>(i - 1))),
//            Point((i)*bin_w, hist_h - cvRound(b_hist.at<float>(i))), Scalar(255, 0, 0), 2, LINE_AA);
//        //绘制绿色分量直方图
//        line(histImage, Point((i - 1) * bin_w, hist_h - cvRound(g_hist.at<float>(i - 1))),
//            Point((i)*bin_w, hist_h - cvRound(g_hist.at<float>(i))), Scalar(0, 255, 0), 2, LINE_AA);
//        //绘制红色分量直方图
//        line(histImage, Point((i - 1) * bin_w, hist_h - cvRound(r_hist.at<float>(i - 1))),
//            Point((i)*bin_w, hist_h - cvRound(r_hist.at<float>(i))), Scalar(0, 0, 255), 2, LINE_AA);
//    }
//    imshow(output, histImage);
//    waitKey(0);
//    return 0;
//}
//
//

 

标签:14,int,hist,opencv,直方图,图像,include,Mat
来源: https://www.cnblogs.com/MrMKG/p/16052707.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有