OpenCV2编程手册笔记之 4.2计算图像的直方图

来源:互联网 发布:市场大数据分析 编辑:程序博客网 时间:2024/06/10 14:19

在一个单通道的灰度图像中,每个像素的值都介于0(黑色)——255(白色)之间

根据这点,灰度图像的直方图拥有256个条目,这些条目也称之为容器。

现在,我们以灰度形式读取一张图片,并且定义一个直方图处理类来方便的处理直方图操作。

在这个类中,我们先声明变量并编写构造函数:

private:
    int histSize[1];
    float hranges[2];
    const float * ranges[1];
    int channels[1];
public:
    Histogram1D()
    {
        histSize[0] = 256;
        hranges[0] = 0.0;
        hranges[1] = 255.0;
        ranges[0] = hranges;
        channels[0] = 0;
    }

这是一个单通道图像的变量初设值

之后,我们定义一个直方图获取方法:

其中最主要的函数就是calcHist

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 );

images是待处理的图像

nimages是图像的数量,输入1就是一张图片

channels是指针类型,因此在变量声明中使用数组进行声明,代表着图像的通道数,例如灰度图就是单通道

mask是掩码,这里可以默认为cv::Mat

hist是返回的直方图,推荐采用MatND进行定义

dims是维数,一维直方图就输入1就好

histSize是项的数量,也就是容器的数量。但注意它是指针类型,因此变量声明也采用了数组形式。这里有256个容器,因此构造时为256

ranges是像素范围,注意这是一个二维数组。在这个图像中,像素范围是0-255

这里要注意,ranges是float型的,如果使用.at操作获取数值,<>中应为float,后面代码中会看到

其他两个量被opencv初始化,不需要管了

这样,我们只需要初始化对象并调用方法,就可以获取直方图了。


源代码:

class Histogram1D
{
private:
    int histSize[1];
    float hranges[2];
    const float * ranges[1];
    int channels[1];
public:
    Histogram1D()
    {
        histSize[0] = 256;
        hranges[0] = 0.0;
        hranges[1] = 255.0;
        ranges[0] = hranges;
        channels[0] = 0;
    }
    cv::MatND getHistogram(const cv::Mat &image);
};


cv::MatND Histogram1D::getHistogram(const cv::Mat &image)
{
    cv::MatND hist;
    cv::calcHist(&image, 1, channels, cv::Mat(), hist, 1, histSize, ranges);
    return hist;
}


int main()
{
    cv::Mat image = cv::imread("F:\\group.jpg", 0);
    Histogram1D h;
    cv::MatND histo = h.getHistogram(image);
    for (int i = 0; i < 256; i++)
    {
        std::cout << histo.at<float>(i) << std::endl;
    }
    cv::waitKey(0);
    return 0;
}

for这里可以遍历得到数据,注意那个float


--------------------------------------------这时一条华丽的分割线------------------------------------------------------


如果上面看懂了,那么就可以来看看下面

大家可能会了获取直方图,但是用柱状图的方式表示出来,就会显得更加直观

在这个类中,我们首先获取传入图像的直方图数据,并且获得最大值和最小值,这里采取minMaxLoc函数

之后,生成一个空白的长宽都为256的底板图像histImg

由于每个直方图都必然有一个最高点,而这个最高点如果触顶了显得不那么美观。所以,我们设置一个直方图最高点(hpt)来避免这种事情。

之后,就是逐点画出直线了,我们采取比例的办法。例如:

某一个“容器”,例如128这个灰度值,它容纳了1000个点。上文已经知道,最大值是maxVal,那么我们的线的相对长度就是:

hist.at<float>(128) * hpt / maxVal ->128为例计算相对长度

现在,就都做好了。


源代码:

Histogram1D类中的getHistogramImage处理方法:

cv::Mat Histogram1D::getHistogramImage(const cv::Mat &image)
{
    cv::MatND hist = getHistogram(image);
    double maxVal;
    double minVal;
    cv::minMaxLoc(hist, &minVal, &maxVal, 0, 0);
    cv::Mat histImg(histSize[0], histSize[0], CV_8U, cv::Scalar(255));
    int hpt = static_cast<int>(0.9 * histSize[0]);
    for (int h = 0; h < histSize[0]; h++)
    {
        float binVal = hist.at<float>(h);
        int intensity = static_cast<int>(binVal * hpt / maxVal);
        cv::line(histImg, cv::Point(h, histSize[0]), cv::Point(h, histSize[0] - intensity), cv::Scalar::all(0));
    }
    return histImg;
}

这个类中,我想说的是那个减号

用减号的原因大家可以想想,图像的坐标系和坐标变换,在这里就不再叙述了


主函数:

int main()
{
    cv::Mat image = cv::imread("F:\\group.jpg", 0);
    Histogram1D h;
    cv::MatND histo = h.getHistogram(image);
    for (int i = 0; i < 256; i++)
    {
        std::cout << histo.at<float>(i) << std::endl;
    }
    cv::imshow("Histogram", h.getHistogramImage(image));
    cv::waitKey(0);
    return 0;
}

阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 怎么办北京市工会会员互助服务卡 国家发改委录用公示后怎么办 慕课的账号忘了怎么办 清华同方无线鼠标没反应怎么办 全日制专硕考上公务员了怎么办 超出了期刊编辑部审稿时间怎么办 教师晋职称毕业证丢了怎么办 下属部门一直不交材料怎么办 简书投稿被拒绝怎么办 论文引用文献为0怎么办 小米屏幕录制卸载了怎么办 用edius剪的视频卡顿怎么办 微店手机号换号登不进去了怎么办 微信加人被限制怎么办 微信与电脑同步怎么办 微信号盗了红包怎么办 微信被别人登录冻结了怎么办? 微信账号被冻结了怎么办 我微信冻结了怎么办 微信账号冻结了怎么办 微信被冻结里面的钱怎么办 微信账户冻结了怎么办 微信公众号忘记密码怎么办 网课没有刷完怎么办 形势与政策挂了怎么办 苹果录屏声音小怎么办 老师跟学生家长吵起来了怎么办 蓝幕拍摄抠像有蓝色怎么办 学东西悟性不高怎么办 微商不会写笔记怎么办 布鞋买大了一码怎么办 凉鞋买大了一码怎么办 皮鞋小了一码怎么办妙招 图书馆借的书本损坏了怎么办 把人打伤没钱赔怎么办 小孩不小心打伤了老师怎么办 高考进了三段怎么办 工作中和领导产生冲突怎么办 酒店不给员工发工资怎么办 裙子没有解开超市的锁怎么办 接待老外听不懂他说的怎么办