收入囊中

这里的非常多内容事实上在我的Computer
Vision: Algorithms and ApplicationsのImage processing
中都有讲过
  • 相关和卷积工作原理
  • 边界处理
  • 滤波器的工作原理
  • 会使用均值滤波,高斯滤波
  • 使用自己创造的核函数进行双线性滤波
  • 可分离的滤波(加速)

葵花宝典

相关: g=f⊗h

卷积: g=f∗h 

临时不考虑边缘。所以8*8的图形进行相关或卷积操作后就得到6*6的图形
由于我们的h(有时叫做核函数)是中心对称的,所以相关和卷积得到的结果是一样的
那不一样呢?看以下的样例,用个一维的样例,{x,y}是核函数,{a,b,c,d,e}是数据
这里构造核  与数据列表的卷积.
In[1]:=
Out[1]=
这里构造相关.
In[2]:=
Out[2]=
Padding(border effects)
之前提到过,8*8的图像用3*3的核处理会成6*6,那么边界要怎么处理呢?

  • 0填充。非常easy的处理方式
  • 常数填充
  • 夹取填塞(clamp),不断地复制边缘像素的值
  • 重叠填塞(wrap),以环状形态围绕图像进行循环
  • 镜像填塞(mirror),像素围绕图像边界进行镜像反射
  • 延长(extend)。通过在边缘像素值中减去镜像信号的方式延长信号
以下是来自OpenCV的样例,边界处理没有CVAA上面那么丰富
/*
Various border types, image boundaries are denoted with '|' * BORDER_REPLICATE: aaaaaa|abcdefgh|hhhhhhh
* BORDER_REFLECT: fedcba|abcdefgh|hgfedcb
* BORDER_REFLECT_101: gfedcb|abcdefgh|gfedcba
* BORDER_WRAP: cdefgh|abcdefgh|abcdefg
* BORDER_CONSTANT: iiiiii|abcdefgh|iiiiiii with some specified 'i'
*/

滤波器
今天讲的高斯低通滤波器。均值滤波器,双线性滤波器都是起到模糊的作用
低通滤波器抑制了图像的高频部分,使得低频分量畅通
今天是4月28日,在Coursera上有数字信号处理这门课开课。还有在网易公开课有斯坦福的傅立叶变换
假设你想非常深入了解,能够去学一下这两门课
滤波函数有时候又叫核函数,也能够叫算子

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYWJjZDE5OTI3MTln/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />


初识API

均值滤波

C++: void blur(InputArray src,
OutputArray dst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT )
 
  • src – 原始图像
  • dst – 输出图像
  • ksize – 核函数大小
  • anchor – 锚点,普通情况下默觉得(-1,-1)。意味着在中心进行卷积
  • borderType – 边界类型

The function smoothes an image using the kernel:

高斯滤波。对去除正态分布的噪声非常实用

C++: void GaussianBlur(InputArray src,
OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT )
 
  • src – 输入图像
  • dst – 输出图像
  • ksize – 核大小
  • sigmaX – 控制幅度的參数(大家应该都学过或看过高斯函数吧,比方在正态分布中),假设sigmaX,sigmaY都为0,则由核的高度宽度自己计算
  • sigmaY – 二维高斯函数有两个方向能够控制幅度。或这个不设置则和X一样
  • borderType – 边界类型

用自己的核函数进行滤波

C++: void filter2D(InputArray src,
OutputArray dst, int ddepth, InputArray kernel, Point anchor=Point(-1,-1), double delta=0, intborderType=BORDER_DEFAULT )
 
  • src – 输入图像.
  • dst – 输出图像.
  • depth – ddepth=-1,输出图像具有和输入图像一样的depth
  • kernel – 核函数,单通道浮点矩阵
  • anchor – 同之前
  • delta – 可选,直接加到输出图像
  • borderType – 边界类型

荷枪实弹

使用均值滤波

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYWJjZDE5OTI3MTln/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv; Mat src,dst;
int i = 1;
static void change_dst(int, void*)
{
if(i%2 == 0)i++;
blur( src, dst, Size( i, i ), Point(-1,-1));
imshow("dstImage", dst);
} int main( int, char** argv )
{
src = imread( argv[1] );
namedWindow("srcImage", 1);
namedWindow("dstImage", 1); createTrackbar( "mean filter:", "dstImage", &i, 20, change_dst);
change_dst(0, 0); imshow("srcImage", src);
waitKey();
return 0;
}

使用高斯滤波

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYWJjZDE5OTI3MTln/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv; Mat src,dst;
int i = 1;
static void change_dst(int, void*)
{
if(i%2 == 0)i++;
GaussianBlur( src, dst, Size( i, i ), 0, 0 );
imshow("dstImage", dst);
} int main( int, char** argv )
{
src = imread( argv[1] );
namedWindow("srcImage", 1);
namedWindow("dstImage", 1); createTrackbar( "gauss filter:", "dstImage", &i, 20, change_dst);
change_dst(0, 0); imshow("srcImage", src);
waitKey();
return 0;
}

使用自己定义线性滤波


#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv; Mat src,dst,Kernel; int main( int, char** argv )
{
src = imread( argv[1] );
namedWindow("srcImage", 1);
namedWindow("dstImage", 1); Kernel = (Mat_<double>(3,3) << 1, 2, 1, 2, 4, 2, 1, 2, 1)/16; filter2D(src, dst, -1 , Kernel, Point(-1,-1));
imshow("dstImage", dst); imshow("srcImage", src);
waitKey();
return 0;
}

举一反三

可分离的滤波
二维高斯函数卷积能够分两步来进行,首先将图像与一维高斯函数进行卷积,然后将卷积结果与方向垂直的同样一维高斯函数卷积.因此,二维高斯滤波的计算量随滤波模板宽度成线性增长而不是成平方增长。

二维卷积运算,更新一个像素点肯定需要K2 次运算(K是核函数的大小)
文中提出了一种加速的方法,先用一维行向量进行卷积,再用一维列向量进行卷积。假设一个卷积核能够採用这样的方法计算,就是可分离的。(这样子就仅仅有2K次操作。非常神秘吧)

K =vhT  

将卷积核K拆分成列向量v和行向量h

当然。并非全部K都能被拆分。我在上面的图片中的3个样例都是能够拆分的,一维向量已经列在二维以下
最简单的平均滤波,[1,1,1......,1]*[1,1,1......,1]T   = K
再看第3个高斯核,[1,4,6,4,1]*[1,4,6,4,1]T = K
那么怎样推断核函数是不是可分离的呢?CVAA说用神秘值分解的办法
我的想法是,必需要满足中心对称。比方高斯函数,sigmax和sigmay相等的时候就能够分解
OpenCV帮我们实现了
C++: void sepFilter2D(InputArray src,
OutputArray dst, int ddepth, InputArray kernelX, InputArray kernelY, Point anchor=Point(-1,-1), doubledelta=0, int borderType=BORDER_DEFAULT )
 

參数基本没什么好讲,都是一样的,以下我们用这个函数来进行高斯卷积(滤波)

由于效果和之前高斯滤波是一样的。就不贴图了,可是要注意尽管效果一样。可是速度可是大大提升。!
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv; Mat src,dst,kernelX,kernelY; int main( int, char** argv )
{
src = imread( argv[1] );
namedWindow("srcImage", 1);
namedWindow("dstImage", 1); kernelX = (Mat_<double>(1,5) << 1,4,6,4,1)/16;
kernelY = (Mat_<double>(1,5) << 1,4,6,4,1)/16; sepFilter2D(src, dst, -1, kernelX, kernelY);
imshow("dstImage", dst); imshow("srcImage", src);
waitKey();
return 0;
}
计算机视觉讨论群162501053
转载请注明:http://blog.csdn.net/abcd1992719g

OpenCV2马拉松第5圈——线性滤波的更多相关文章

  1. OpenCV2马拉松第15圈——边缘检測(Laplace算子,LOG算子)

    收入囊中 拉普拉斯算子 LOG算子(高斯拉普拉斯算子) OpenCV Laplacian函数 构建自己的拉普拉斯算子 利用拉普拉斯算子进行图像的锐化 葵花宝典 在OpenCV2马拉松第14圈--边缘检 ...

  2. OpenCV2马拉松第17圈——边缘检測(Canny边缘检測)

    计算机视觉讨论群162501053 转载请注明:http://blog.csdn.net/abcd1992719g 收入囊中 利用OpenCV Canny函数进行边缘检測 掌握Canny算法基本理论 ...

  3. OpenCV2马拉松第22圈——Hough变换直线检測原理与实现

    计算机视觉讨论群162501053 转载请注明:http://blog.csdn.net/abcd1992719g/article/details/27220445 收入囊中 Hough变换 概率Ho ...

  4. OpenCV2马拉松第14圈——边缘检測(Sobel,prewitt,roberts)

    收入囊中 差分在边缘检測的角色 Sobel算子 OpenCV sobel函数 OpenCV Scharr函数 prewitt算子 Roberts算子 葵花宝典 差分在边缘检測究竟有什么用呢?先看以下的 ...

  5. OpenCV2马拉松第2圈——读写图片

    收入囊中 用imread读取图片 用nameWindow和imshow展示图片 cvtColor彩色图像灰度化 imwrite写图像 Luv色彩空间转换 初识API 图像读取接口 image = im ...

  6. OpenCV2马拉松第10圈——直方图反向投影(back project)

    收入囊中 灰度图像的反向投影 彩色图像的反向投影 利用反向投影做object detect 葵花宝典 什么是反向投影?事实上没有那么高大上! 在上一篇博文学到,图像能够获得自己的灰度直方图. 反向投影 ...

  7. OpenCV2马拉松第12圈——直方图比較

    收入囊中 使用4种不同的方法进行直方图比較 葵花宝典 要比較两个直方图, 首先必需要选择一个衡量直方图相似度的对照标准.也就是先说明要在哪个方面做对照. 我们能够想出非常多办法,OpenCV採用了下面 ...

  8. openCV2马拉松第19圈——Harris角点检測(自己实现)

    计算机视觉讨论群162501053 转载请注明:http://blog.csdn.net/abcd1992719g/article/details/26824529 收入囊中 使用OpenCV的con ...

  9. openCV2马拉松第18圈——坐标变换

    计算机视觉讨论群162501053 转载请注明:http://blog.csdn.net/abcd1992719g 收入囊中 仿射变换 坐标映射 利用坐标映射做一些效果,例如以下 watermark/ ...

随机推荐

  1. 分布式事务框架-fescar

    https://github.com/alibaba/fescar/wiki/%E6%A6%82%E8%A7%88?spm=5176.11156381.0.0.b9f85ceegUXvCC

  2. vue+iview中的table表格导出excel表格

    一.iveiw框架中table中有exportCsv()方法可以导出.csv后缀文件,类似于excel文件,但是并不是excel文件. 二.实现table表格导出excel文件利用Blob.js 和 ...

  3. oracle db 产品路线图

    Release Schedule of Current Database Releases (文档 ID 742060.1)

  4. Mybatis学习笔记6 - #{}和${}

    #{}:可以获取map中的值或者pojo对象属性的值.${}:可以获取map中的值或者pojo对象属性的值. 区别: #{}:是以预编译的形式,将参数设置到sql语句中:PreparedStateme ...

  5. Unity GameObject.FindObjectOfType<>(); 按类型查找游戏对象

    FindObjectOfType<>()   是按类型查找游戏对象.<>里面填写类型,那要是有多个这种类型的呢?来试一下. 1. 新建一个场景,新建一个Test.cs脚本,内容 ...

  6. Host 'XXX' is not allowed to connect to this MySQL server解决方案

    如何允许远程连接mysql数据库呢,操作如下: 首先登录账号 mysql -uroot -p 使用mysql用户 use mysql 如果报此类错:ERROR 1820 (HY000): You mu ...

  7. winscp介绍与使用

    winscp介绍 WinSCP 是一个 Windows 环境下使用的 SSH 的开源图形化 SFTP 客户端.同时支持 SCP 协议.它的主要功能是在本地与远程计算机间安全地复制文件,并且可以直接编辑 ...

  8. LeetCode 167.两数之和(C++)

    给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数. 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2. 说明: 返回的下标值 ...

  9. [原创]Dubbo配置(Spring4+Hiberante4+Druid)

    如果dubbo使用注解,并且spring也使用注解,如使用事务,则dubbo加过注解的类无法发布. <?xml version="1.0" encoding="UT ...

  10. pat1002. A+B for Polynomials (25)

    1002. A+B for Polynomials (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue T ...