当前位置: 首页 > news >正文

13---OpenCV:图像进阶操作之①图像直方图②图像金字塔

一、图像直方图

        在分析图像、物体和视频信息的时候,我们经常用直方图来表达我们关注的信息。直方图在计算机视觉中应用广泛。例如,通过判断帧与帧之间边缘和颜色的统计量是否出现巨大变化,来检测视频中场景的变换数字图像处理中,通常使用的是灰度直方图,灰度直方图是一种计算代价非常小但很有用的工具,它概括了一幅图像的灰度级信息。灰度直方图是图像灰度级的函数,用来描述每个灰度级在图像矩阵中的像素个数或者占有率。直方图分布较广较均匀的图像对比度高,视觉效果好。

API介绍

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 );
/*******************************************************************
*           images:         输入图         
*           nimages:        输入图个数
*           channels:       统计第几通道
*           mask:           掩膜
*           hist:           数组存储输出值
*           dims:           输出直方图维度         
*           histSize:       直方图区间
*           ranges:         统计像素区间
*           uniform:       直方图数组是否归一化处理
*           accumulate:    多图时是否累计计算
*********************************************************************/
void calcHist( const Mat* images, int nimages, const int* channels, InputArray mask,SparseMat& hist, int dims,const int* histSize, const float** ranges,bool uniform = true, bool accumulate = false );
/*******************************************************************
*           images:         输入图         
*           nimages:        输入图个数
*           channels:       统计第几通道
*           mask:           掩膜
*           hist:           图像存储输出值
*           dims:           输出直方图维度         
*           histSize:       直方图区间
*           ranges:         统计像素区间
*           uniform:       直方图数组是否归一化处理
*           accumulate:    多图时是否累计计算
*********************************************************************/
void calcHist( InputArrayOfArrays images,const std::vector<int>& channels,InputArray mask, OutputArray hist,const std::vector<int>& histSize,const std::vector<float>& ranges,bool accumulate = false );
/*******************************************************************
*           images:         输入图         
*           channels:       变换矩阵
*           mask:           输出图大小
*           hist:           数组存储输出值
*           histSize:       直方图区间
*           ranges:         统计像素区间
*           accumulate:    多图时是否累计计算
*********************************************************************/

综合代码

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
class Hist 
{
public:
    Hist(string url = "./mm.jpg") :img(imread(url)) 
    {
        hist["img"] = img;
    }
    void TestCalcHist() 
    {
        split(img, bgr);
        //准备直方图的参数
        Mat Blue, Green, Red;
        const int channerl[] = { 0 };
        const int histSize[] = { 256 };
        float rang[] = { 0,255 };
        const float* ranges[] = { rang };
​
        calcHist(&bgr[0], 1, channerl, Mat(), Blue, 1, histSize, ranges);
        calcHist(&bgr[1], 1, channerl, Mat(), Green, 1, histSize, ranges);
        calcHist(&bgr[2], 1, channerl, Mat(), Red, 1, histSize, ranges);
        //绘制直方图
        int width = 500;
        int height = 300;
        hist["hist"] = Mat(height, width, CV_8UC3, Scalar(0, 0, 0));
        //归一化处理
        normalize(Blue, Blue, 0, 300, NORM_MINMAX);
        normalize(Green, Green, 0, 300, NORM_MINMAX);
        normalize(Red, Red, 0, 300, NORM_MINMAX);
        //比例问题
        int step = cvRound(float(width) / float(256));   //每一个点的占比
        for (int i = 1; i < 256; i++) 
        {
            line(hist["hist"], Point(step * (i - 1), height - cvRound(Blue.at<float>(i - 1))), Point(step * (i), height - cvRound(Blue.at<float>(i))),Scalar(255,0,0));
            line(hist["hist"], Point(step * (i - 1), height - cvRound(Blue.at<float>(i - 1))), Point(step * (i), height - cvRound(Green.at<float>(i))), Scalar(0, 255, 0));
            line(hist["hist"], Point(step * (i - 1), height - cvRound(Blue.at<float>(i - 1))), Point(step * (i), height - cvRound(Red.at<float>(i))), Scalar(0, 0, 255));
        }
    }
​
    void Show() 
    {
        for (auto& v : hist) 
        {
            imshow(v.first, v.second);
        }
        waitKey(0);
    }
​
protected:
    Mat img;
    map<string, Mat> hist;
    vector<Mat> bgr;
};
​
int main() 
{
    unique_ptr<Hist> p(new Hist);
    p->TestCalcHist();
    p->Show();
    return 0;
}

二、图像金字塔

图像金字塔有两种,

  • 高斯金字塔:高斯金字塔用来向下采样

  • 拉普拉斯金字塔:图像底层图像重建上层未采样图像

在数据图像处理中,就是数据残差,可以对图像进行最大程度的还原,配合高斯金字塔—起使用。

高斯金字塔

高斯金字塔是由底部的最大分辨率图像逐次向下采样得到的一系列图像。最下面的图像分辨率最高,越往上图像分辨率越低。高斯金字塔的向下采样过程是:对于给定的图像先做一次高斯平滑处理,也就是使用一个卷积核对图像进行卷积操作,再对图像采样,去除图像中的偶数行和偶数列,然后就得到一幅图片,对这幅图片再进行上述操作,就可以得到高斯金字塔。

拉普拉斯金字塔

拉普拉斯金字塔与高斯金字塔正好相反,高斯金字塔通过底层图像构建上层图像,而拉普拉斯是通过上层小尺寸的图像构建下层大尺寸的图像。主要应用于图像融合,即是通过残差来还原原图。

图像向上采样是由小图像不断放大的过程。它将图像在每个方向上扩大为原图像的⒉倍,新增的行和列均用0来填充,并使用与“向下采样”相同的卷积核乘以4,再与放大后的图像进行卷积运算,以获得“新增像素”的新值。所有元素都被规范化为4,而不是1。值得注意的是,放大后的图像比原始图像要模糊。

 API介绍

//向下采样
void pyrDown( InputArray src, OutputArray dst,const Size& dstsize = Size(), int borderType = BORDER_DEFAULT );
/*******************************************************************
*           src:            输入图         
*           dst:            输出图
*           dstsize:        卷积核大小
*           borderType:     边界模式
*********************************************************************/
//向上采样
void pyrUp( InputArray src, OutputArray dst,const Size& dstsize = Size(), int borderType = BORDER_DEFAULT );
/*******************************************************************
*           src:            输入图         
*           dst:            输出图
*           dstsize:        卷积核大小
*           borderType:     边界模式
*********************************************************************/

综合代码

#include <iostream>
#include <string>
#include <map>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
class Pyr 
{
public:
    Pyr() :img(imread("20.jpg")) 
    {
        pyr["img"] = img;
    }
    void TestPyrDown() 
    {
        pyrDown(img, pyr["d1"]);
        pyrDown(pyr["d1"], pyr["d2"]);
        pyrDown(pyr["d2"], pyr["d3"]);
    }
    void TestPyrUp() 
    {
        pyrUp(img, pyr["u1"]);
        pyrUp(pyr["u1"], pyr["u2"]);
        //pyrUp(pyr["u2"], pyr["u3"]);
    }
    void Show() 
    {
        int i = 0;
        for (auto& v : pyr) 
        {
            imshow(v.first, v.second);
            moveWindow(v.first, i++ * 100, 100);
        }
        waitKey(0);
    }
protected:
    Mat img;
    map<string, Mat> pyr;
};
​
int main() 
{
    unique_ptr<Pyr> p(new Pyr);
    p->TestPyrUp();
    p->TestPyrDown();
    p->Show();
    return 0;
}

 

相关文章:

  • 石头科技: 决胜百亿扫地机器人“价值高地”
  • 趁着中秋节来临之际,学学如何做好团队管理
  • Spring Cloud项目(八)——使用gateway作为服务网关
  • 为什么要注册商标?有什么好处?
  • C/C++后端开发学习路线总结(附带实习学习经历分享)
  • 广西大学口袋开发板之抢答器
  • 【Python零基础入门篇 · 2】:掌握各种运算符和变量、input()输入输出、映射函数map()结合input()和split()函数实现多值输入
  • 单向环形链表构建(思路分析) [Java][数据结构]
  • 数智随行 | 探想未来工厂数字化,强化智能设备管理
  • 解决所有二叉树路径问题
  • Apache Kyuubi 在小米大数据平台的应用实践
  • 论文阅读(8)Cool your jets:海洋无脊椎动物的生物喷射推进(2021)
  • Git基本应用<一>:Git安装及GitHub连接
  • Java实现阿里云OSS上传文件
  • NP管理器 NPManager v3.0.49 安卓APK逆向反编译工具
  • 【技术性】Search知识
  • 〔开发系列〕一次关于小程序开发的深度总结
  • Android交互
  • Apache的基本使用
  • JavaScript设计模式与开发实践系列之策略模式
  • linux学习笔记
  • Ruby 2.x 源代码分析:扩展 概述
  • tweak 支持第三方库
  • 从零开始在ubuntu上搭建node开发环境
  • 后端_ThinkPHP5
  • 基于游标的分页接口实现
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 详解移动APP与web APP的区别
  • 你对linux中grep命令知道多少?
  • 《码出高效》学习笔记与书中错误记录
  • kubernetes资源对象--ingress
  • puppet连载22:define用法
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (Ruby)Ubuntu12.04安装Rails环境
  • (二)linux使用docker容器运行mysql
  • (力扣)循环队列的实现与详解(C语言)
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (四)c52学习之旅-流水LED灯
  • (转)关于如何学好游戏3D引擎编程的一些经验
  • (转)重识new
  • (转载)在C#用WM_COPYDATA消息来实现两个进程之间传递数据
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • .[hudsonL@cock.li].mkp勒索病毒数据怎么处理|数据解密恢复
  • .net oracle 连接超时_Mysql连接数据库异常汇总【必收藏】
  • .net 反编译_.net反编译的相关问题
  • .net遍历html中全部的中文,ASP.NET中遍历页面的所有button控件
  • [20170728]oracle保留字.txt
  • [2021 蓝帽杯] One Pointer PHP
  • [AIGC 大数据基础]hive浅谈
  • [BT]BUUCTF刷题第4天(3.22)
  • [C#基础知识系列]专题十七:深入理解动态类型
  • [c++] 什么是平凡类型,标准布局类型,POD类型,聚合体
  • [C++11 多线程同步] --- 条件变量的那些坑【条件变量信号丢失和条件变量虚假唤醒(spurious wakeup)】