美文网首页计算机图像理论opencv及vslamOpenCv
opencv图像灰度直方图显示--Apple的学习笔记

opencv图像灰度直方图显示--Apple的学习笔记

作者: applecai | 来源:发表于2019-12-24 21:25 被阅读0次

    前言

    学以致用,乐趣无穷。由于元旦要旅游,所以把手机中现有照片都copy到PC备份,腾出空间,但是这些照片有些重复,有些无用,有些存在曝光问题,我能否自己做个程序自动帮我识别出高质量的图片保存,其它照片删除呢?

    为了达成这个应用目的,我进行了任务拆分,首要要识别图片质量,有没有标准呢?就是说图像质量标准是什么呢?网上还真的搜索到了,包括有图像分析软件lmatest等。接着就是自动处理图片,然后按我的标准进行高质量图片分类。

    图像分析

    今天的主题围绕图像分析,图像的三要素包括亮度,对比图,饱和度。今天就是要用代码来分析出图像的灰度直方图。

    主要函数

    包括calcHist计算灰度直方图和normalize归一化

    C++: void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false )
    
    参数详解:
    onst Mat* images:输入图像
    int nimages:输入图像的个数
    const int* channels:需要统计直方图的第几通道
    InputArray mask:掩膜,,计算掩膜内的直方图  ...Mat()
    OutputArray hist:输出的直方图数组
    int dims:需要统计直方图通道的个数
    const int* histSize:指的是直方图分成多少个区间,就是 bin的个数
    const float** ranges: 统计像素值得区间
    bool uniform=true::是否对得到的直方图数组进行归一化处理
    bool accumulate=false:在多个图像时,是否累计计算像素值得个数
    
    void cv::normalize(InputArry src,InputOutputArray dst,double alpha=1,double beta=0,int norm_type=NORM_L2,int dtype=-1,InputArray mark=noArry())
    参数说明
    src        输入数组;
    dst        输出数组,数组的大小和原数组一致;
    alpha      1,用来规范值,2.规范范围,并且是下限;
    beta       只用来规范范围并且是上限;使用范围归一化时,beta必有值不等于0。
    norm_type  归一化选择的数学公式类型;
    dtype      当为负,输出在大小深度通道数都等于输入,当为正,输出只在深度与输如不同,不同的地方游dtype决定;
    mark       掩码。选择感兴趣区域,选定后只能对该区域进行操作。
    

    备注:直接传递Mat(),代表为空。图像中的坐标(0,0)在左上角,向下为y轴数值增大的方向,向右为x轴数值增大的方向。

    实现代码

    #include "stdafx.h"
    #include <opencv2/imgproc.hpp>
    #include <opencv2/highgui.hpp>
    using namespace std;
    using namespace cv;
    
    int main()
    {
    
        Mat srcImage = imread("D:\\vcpro\\opencv\\pic\\IMG_20191013_104201.jpg", IMREAD_GRAYSCALE);//IMREAD_COLOR); // 直接导入图像为单通道灰度图
        imshow("【原图】", srcImage);
        int channels = 0;
        MatND dstHist;
        //接下来是直方图的每一个维度的柱条的数目 
        int histSize[] = { 256 };
        //定义变量用来存储单个维度的数值的取值范围 
        float midRanges[] = { 0, 256 };
        const float *ranges[] = { midRanges };
    
        calcHist(&srcImage, 1, &channels, Mat(), dstHist, 1, histSize, ranges, true, false);
        //dstHist变量中将储存了直方图的信息;
        //用dstHist的模版函数 at<Type>(i)得到第i个柱条的值  
        int hist_h = 400;  //row
        int hist_w = 512;  //col
        int bin_w = hist_w / histSize[0];
        Mat histImage(hist_h, hist_w, CV_8UC3, Scalar(0, 0, 0));
        normalize(dstHist, dstHist, 0, hist_h, NORM_MINMAX, -1, Mat());
        for (int i = 0; i < histSize[0]; i++)
        {
            //line(histImage, Point(i*bin_w, 400), Point(i*bin_w, 390), Scalar(255, 0, 0));
            line(histImage, Point(i*bin_w, hist_h), Point((i)*bin_w, hist_h - cvRound(dstHist.at<float>(i))), Scalar(255, 0, 0));
        }
        imshow("【直方图】", histImage);
        waitKey(0);
        return 0;
    }
    

    直方图效果

    效果.png

    相关文章

      网友评论

        本文标题:opencv图像灰度直方图显示--Apple的学习笔记

        本文链接:https://www.haomeiwen.com/subject/actqoctx.html