小言_互联网的博客

opencv图像金字塔之上采样、降采样、高斯不同、图像归一化

489人阅读  评论(0)

概述

  • 高斯金字塔 用来对图像进行降采样
  • 拉普拉斯金字塔 用来重建一张图片(根据它的上层降采样图片)

高斯金字塔

  • 高斯金字塔是从底向上,逐层降采样得到
  • 降采样之后图像大小为原图像的四分之一,就是对原图像进行删除偶数行与列的操作,即可得到降采样之后的上一层图片
  • 高斯金字塔生成分为两步
    • 对当前层进行高斯模糊
    • 删除当前层的偶数行、列

高斯不同(Different of Gaussian-DOG)

  • 定义:就是把同一张图像在不同参数下做高斯模糊之后的结果相减,得到的输出图像,称为高斯不同(DOG)
  • 高斯不同是图像的内在特征,在灰度图像增强,角点检测,图像边缘检测中经常用到

拉普拉斯金字塔

  • 拉普拉斯金字塔是从上向下,逐层升采样得到
  • 升采样之后图像大小为原图像的四倍,就是对原图像进行添加偶数行与列的操作,用0补充,卷积预测某些位置像素得到下一层图片
    1/16*
    [ 1 4 6 4 1 4 16 24 16 4 6 24 36 24 6 4 16 24 16 4 1 4 6 4 1 ] \left [ \begin{matrix} 1 & 4 & 6 & 4 & 1 \\ 4 & 16 & 24 & 16 & 4 \\ 6& 24 & 36 & 24 & 6 \\ 4 & 16 & 24 & 16 & 4 \\ 1 & 4 & 6 & 4 & 1 \end{matrix} \right]
. 1 4 6 4 1
4 16 24 16 4
1/16 6 24 36 24 6
4 16 24 16 4
1 4 6 4 1

采样相关API

降采样:

void pyrDown(InputArray src, OutputArray dst, const Size& dstsize=Size())
参数说明

tmp: 当前图像, 初始化为原图像`src`。
dst: 目的图像,显示图像,为输入图像的1/4
Size(tmp.cols/2, tmp.rows/2): 目的图像大小, 既然我们是向下采样,pyrDown期待一个于输入图像tmp1/4大小。

上采样

void pyrUp(InputArray src, OutputArray dst, const Size& dstsize=Size())
参数说明:

tmp: 当前图像, 初始化为原图像 src
dst: 目的图像,显示图像,为输入图像的两倍
**Size( tmp.cols2, tmp.rows2 ) **: 目的图像大小, 既然我们是向上采样, pyrUp期待一个两倍于输入图像tmp的大小。


代码演示

#include <iostream>  
#include <fstream>
#include <opencv2/opencv.hpp>

#define Pic_Path "/home/image/Pictures/" 
#define Pic_Name "demo.jpg" 

using namespace std;
using namespace cv;
int main(int argc, char **argv)
{
    string pic = string(Pic_Path) + string(Pic_Name);
    cout << pic << endl;
    
    Mat src,downImage, upImage;
    src = imread(pic.c_str());
    imshow("src", src);

    //每次只能放大或缩小一倍,不能跳着放大
    pyrDown(src, downImage, Size(src.cols >> 1, src.rows >> 1)); //降采样 缩小
    pyrUp(src, upImage, Size(src.cols << 1, src.rows << 1));  //上采样 放大
    imshow("pryDown", downImage);
    imshow("pryUp", upImage);
    
    waitKey(0);
    return 0;
}


补充API

图像相减函数

cv::subtract(image1, image2, outimage);
参数介绍:

  • image1 被减数(输入图像1)
  • image2 减数(输入图像2)
  • outimage 差(差值图像)
  • 其余参数 没有列出,选择默认即可

图像归一化函数

void cv::normalize(InputArry src,InputOutputArray dst,double alpha=1,double beta=0,int norm_type=NORM_L2,int dtype=-1,InputArray mark=noArry())

参考链接:https://www.wandouip.com/t5i177048/
参考链接:https://blog.csdn.net/kuweicai/article/details/78988886

参数介绍:

  • src 输入图像;
  • dst 输出图像,图像的大小和原图像一致;
  • alpha 1,用来规范值,2.规范范围,并且是下限;
  • beta 只用来规范范围并且是上限;
  • norm_type 归一化选择的数学公式类型;
    • NORM_MINMAX:数组的数值被平移或缩放到一个指定的范围,线性归一化。
    • NORM_INF: 归一化数组的(切比雪夫距离)L∞范数(绝对值的最大值)
    • NORM_L1 : 归一化数组的(曼哈顿距离)L1-范数(绝对值的和)
    • NORM_L2: 归一化数组的(欧几里德距离)L2-范数
  • dtype 当为负,输出在大小深度通道数都等于输入,当为正,输出只在深度与输如不同,不同的地方游dtype决定;
  • mark 掩码。选择感兴趣区域,选定后只能对该区域进行操作

d s t ( r , c ) dst(r,c) = ( b a ) (b-a)* s r c ( r , c ) m i n ( s r c ) m a x ( s r c ) m i n ( s r c ) \frac{src(r,c)-min(src)}{max(src)-min(src)}

NORM_MINMAX 线性归一化详解

  • alphabeta分别为归一化后的最小值、最大值,函数会自动判断哪个为最大值,最小值
  • 再求dst
    以数列*{ 2.0, 6.0, 7.0, 8.0, 10.0}*为例, alpha=5, beta=100
    公式如下:
b = max(alpha, beta)
a = min(alpha, beta)
alpha=5, beta=100
b = max(alpha, beta) = 100
a = min(alpha, beta) = 5
dst[0] = (100-5) * (2-2)/ (10-2) +5 = 2
dst[1] = (100-5) * (6-2)/ (10-2) +5 = 52.5
  • alpha=1, beta=0
Original NORM_L1 NORM_L2 NORM_INF NORM_MINMAX
2.00 0.060606061 0.125738923 0.2 0
6.00 0.181818182 0.377216768 0.6 0.5
7.00 0.212121212 0.440086229 0.7 0.625
8.00 0.242424242 0.502955691 0.8 0.75
10.00 0.303030303 0.628694613 1 1
  • alpha=3, beta=7
Original NORM_L1 NORM_L2 NORM_INF NORM_MINMAX
2.00 0.181818182 0.377216768 0.6 3
6.00 0.545454545 1.131650304 1.8 5
7.00 0.636363636 1.320258688 2.1 5.5
8.00 0.727272727 1.508867072 2.4 6
10.00 0.909090909 1.88608384 3 7
  • alpha=5, beta=100
Original NORM_L1 NORM_L2 NORM_INF NORM_MINMAX
2.00 0.30303 0.628695 1 5
6.00 0.909091 1.88608 3 52.5
7.00 1.06061 2.20043 3.5 64.375
8.00 1.21212 2.51478 4 76.25
10.00 1.51515 3.14347 5 100

函数作用意义

一般用在预处理,这里只介绍线性变换归一化,作用是把不同尺度的图片,经过线性尺度变化到另一空间范围,比如一张图片比较黑像素分布范围在012之间,查看图片基本是全黑图片,我们将图片像素范围延伸至0255之间,分布在012之间的像素点将进行线性拓展至0255,像素点之间差异化增大,图片对比度更强显示细节更加明晰。反之同理


图像位操作API

bitwise_and、bitwise_or、bitwise_xor、bitwise_not

void bitwise_and(InputArray src1, InputArray src2,OutputArray dst, InputArray mask=noArray());//dst = src1 & src2
void bitwise_or(InputArray src1, InputArray src2,OutputArray dst, InputArray mask=noArray());//dst = src1 | src2
void bitwise_xor(InputArray src1, InputArray src2,OutputArray dst, InputArray mask=noArray());//dst = src1 ^ src2
void bitwise_not(InputArray src, OutputArray dst,InputArray mask=noArray());//dst = ~src

函数介绍

  • bitwise_and是对二进制数据进行“与”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“与”操作,1&1=1,1&0=0,0&1=0,0&0=0
  • bitwise_or是对二进制数据进行“或”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“或”操作,1|1=1,1|0=0,0|1=0,0|0=0
  • bitwise_xor是对二进制数据进行“异或”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“异或”操作,11=0,10=1,01=1,00=0
  • bitwise_not是对二进制数据进行“非”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“非”操作,1=0,0=1

代码演示

#include <iostream>  
#include <fstream>
#include <opencv2/opencv.hpp>

#define Pic_Path "/home/image/Pictures/" 
#define Pic_Name "demo.jpg" 

using namespace std;
using namespace cv;
int main(int argc, char **argv)
{
    string pic = string(Pic_Path) + string(Pic_Name);
    cout << pic << endl;
	
    
    Mat src,downImage, upImage;
    src = imread(pic.c_str());
    imshow("src", src);

    //每次只能放大或缩小一倍,不能跳着放大
    pyrDown(src, downImage, Size(src.cols >> 1, src.rows >> 1)); //降采样 缩小
    pyrUp(src, upImage, Size(src.cols << 1, src.rows << 1));  //上采样 放大
    imshow("pryDown", downImage);
    imshow("pryUp", upImage);

    //Difference of Gaussian(DOG) 高斯不同
    Mat gray_image, g1, g2 , dogImage;
    
    //图片转化为灰度图片
    cvtColor(src, gray_image, CV_BGR2GRAY);
    
    //对图片进行一次高斯模糊
    GaussianBlur(gray_image, g1, Size(3,3),0);
    
    //对图片进行二次高斯模糊
    GaussianBlur(g1, g2, Size(3, 3), 0);
    
  
    //图像相减 可以获得图像的边缘信息 细节显示力很弱难以分辨
    subtract(g1, g2, dogImage);
    cv::imshow("图像相减",dogImage);
    
    /*
    图像相减后图片太暗基本全黑,细节展示不清晰,像素集中在数值较低的区域,需进行线性归一化,将像素范围扩展之更大范围
    使稍微明亮的点更加明亮
    */
    //图像归一化  增强细节显示
    //参数一 原图像
    //参数二 目标图像
    //参数三 归一化上限值
    //参数四 归一化下限值
    //归一化选择的数学公式
    normalize(dogImage, dogImage, 0, 255, NORM_MINMAX);
    cv::imshow("归一化",dogImage);
    
    //对图片进行取反突出细节显示
    bitwise_not(dogImage, dogImage);
    imshow("DOG翻转颜色显示", dogImage);

    waitKey();
    return 0;
}

转载:https://blog.csdn.net/z961968549/article/details/102589033
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场