图像处理_滤波器

(1)图像的平滑处理

图像的平滑也称模糊,平滑处理需要一个滤波器,最常用的滤波器就是线性滤波器,线性滤波器的输出像素值是g(x,y),是输入像素值是  f(x,y)的加权和:                                                                                    

h( k,l )称为核,它仅仅是一个加权系数,那么滤波器有很多种,最常用的滤波器介绍如下:

归一化块滤波器:是比较简单的滤波器,输出的像素值是核窗口内像素值的均值(所有像素的加权系数相等),核如下:

高斯滤波器:最有用的滤波器。高斯滤波器是将输入数组的每一个像素点与高斯内核卷积,将卷积当作输出像素值,比如一维高斯函数的:

可以发现中间像素的加权系数最大,周边的像素的加权系数随着它们远离中间像素的距离的增大而减小,二维高斯函数的表达式是

其中u为均值,峰值对应的位置,o是代表标准差,变量x,y各有一个均值,也各有一个标准差

中值滤波器:将图像的每一个像素用领域像素的中值替代(以当前像素为中心的正方形区域)

双边滤波器:类似与高斯滤波器,双边滤波器也给每一个领域像素分配一个加权系数,这个加权系数包含两个部分,第一部分加权方式与高斯滤波一样(是有几何空间距离决定滤波器的系数),第二部分的权重则取决于该领域像素与当前像素的灰度差值,是一种可以包边去噪的滤波器

双边滤波器中输出滤波器的值依赖于邻域像素值的加权组合

权重系数w(i,j,k,l)取决于定义域核

和值域核

的卷积

源码与结果

#include <iostream>
#include <vector>#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/features2d/features2d.hpp"using namespace std;
using namespace cv;/// 全局变量
int DELAY_CAPTION = 1500;
int DELAY_BLUR = 100;
int MAX_KERNEL_LENGTH = 31;   //最大的核长度Mat src; Mat dst;
char window_name[] = "Smoothing Demo";/// Function headers函数声明
int display_caption( const char* caption );
int display_dst( int delay );/*** function main*/
int main( void )
{namedWindow( window_name, WINDOW_AUTOSIZE );///载入原图想src = imread( "/home/salm/myopencv/images/cat.jpg", 1 );if( display_caption( "Original Image" ) != 0 ) { return 0; }dst = src.clone();if( display_dst( DELAY_CAPTION ) != 0 ) { return 0; }/// Applying Homogeneous blur    使用均值平滑
/*blur归一化块滤波src: 输入图像dst: 输出图像Size( w,h ): 定义内核大小( w 像素宽度, h 像素高度)Point(-1, -1): 指定锚点位置(被平滑点), 如果是负值,取核的中心为锚点。
*/if( display_caption( "Homogeneous Blur" ) != 0 ) { return 0; }for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 ){ blur( src, dst, Size( i, i ), Point(-1,-1) );if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }/// Applying Gaussian blur     使用高斯平滑if( display_caption( "Gaussian Blur" ) != 0 ) { return 0; }for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 ){ GaussianBlur( src, dst, Size( i, i ), 0, 0 ); //Size(w, h): 定义内核的大小(需要考虑的邻域范围)。 w 和 h 必须是正奇数,否则将使用 \sigma_{x} 和 \sigma_{y} 参数来计算内核大小if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }/// Applying Median blur    中值滤波if( display_caption( "Median Blur" ) != 0 ) { return 0; }for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 ){ medianBlur ( src, dst, i );  //i: 内核大小 (只需一个值,因为我们使用正方形窗口),必须为奇数if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }/// Applying Bilateral Filter  双边滤波
/*
bilateral执行双边滤波操作src: 输入图像dst: 输出图像d: 像素的邻域直径sigma_{Color}: 颜色空间的标准方差sigma_{Space}: 坐标空间的标准方差(像素单位)
*/if( display_caption( "Bilateral Blur" ) != 0 ) { return 0; }for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 ){ bilateralFilter ( src, dst, i, i*2, i/2 );if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }/// Wait until user press a keydisplay_caption( "End: Press a key!" );waitKey(0);return 0;
}/*** @function display_caption*/
int display_caption( const char* caption )
{dst = Mat::zeros( src.size(), src.type() );putText( dst, caption,Point( src.cols/4, src.rows/2),FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) );imshow( window_name, dst );int c = waitKey( DELAY_CAPTION );if( c >= 0 ) { return -1; }return 0;
}/*** @function display_dst*/
int display_dst( int delay )
{imshow( window_name, dst );int c = waitKey ( delay );if( c >= 0 ) { return -1; }return 0;
}

结果为

腐蚀与膨胀(Eroding and Dilating)

形态学操作是基于形状的一系列图像处理操作,通过结构元素作用于输入图像来产生输出图像,最基本的形态学操作有两种:erision  与  dilation  它们的应用广泛,主要有消除噪声,分割独立的图像元素,连接相邻的元素,寻找图像中明显的极大值或极小值区域

通俗的说:膨胀算法是图像扩大一圈,腐蚀算法是图像缩小一圈,腐蚀是删除对象边界的某些元素,膨胀是给图像的边界添加某些元素,算法从图像的角度来看,二值图像的腐蚀与膨胀就是将一个小型的二值图像(比如一般为结构元素  一般为3*3的)在图像上进行逐点的运动并比较,根据比较的结果做出相应的处理。

膨胀算法:用3*3的结构元素,扫描二值图像的每一个像素,用结构元素与其覆盖的二值图像做“与”运行,如果都为“0”结构图像的该元素就为0  否则就为1   结果会使得二值图像扩大一圈

腐蚀算法:用3*3的结果元素,扫描二值图像的每一个像素,用结构元素与其覆盖的二值图像做“与”运算,结构都为1  结构图像的该元素就为1  否则就为0   结果使二值图像减小一圈

OpenCV里面的腐蚀膨胀都是针对 白色 目标区域的。说膨胀使图像 变大一圈, 那是指 图像中的 白色目标区域 扩大了一圈

源码

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>using namespace cv;/// Global variables 全局变量
Mat src, erosion_dst, dilation_dst;int erosion_elem = 0;
int erosion_size = 0;
int dilation_elem = 0;
int dilation_size = 0;
int const max_elem = 2;
int const max_kernel_size = 21;//函数申明
void Erosion( int, void* );
void Dilation( int, void* );int main( int, char** argv )
{/// Load an imagesrc = imread( argv[1] );if( !src.data ){ return -1; }/// Create windowsnamedWindow( "Erosion Demo", WINDOW_AUTOSIZE );namedWindow( "Dilation Demo", WINDOW_AUTOSIZE );moveWindow( "Dilation Demo", src.cols, 0 );/// Create Erosion TrackbarcreateTrackbar( "Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Erosion Demo",&erosion_elem, max_elem,Erosion );createTrackbar( "Kernel size:\n 2n +1", "Erosion Demo",&erosion_size, max_kernel_size,Erosion );/// Create Dilation TrackbarcreateTrackbar( "Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Dilation Demo",&dilation_elem, max_elem,Dilation );createTrackbar( "Kernel size:\n 2n +1", "Dilation Demo",&dilation_size, max_kernel_size,Dilation );/// Default startErosion( 0, 0 );Dilation( 0, 0 );waitKey(0);return 0;
}/*
内核选择三种形状之一:矩形: MORPH_RECT交叉形: MORPH_CROSS椭圆形: MORPH_ELLIPSE
*/
void Erosion( int, void* )
{int erosion_type = 0;if( erosion_elem == 0 ){ erosion_type = MORPH_RECT; }else if( erosion_elem == 1 ){ erosion_type = MORPH_CROSS; }else if( erosion_elem == 2) { erosion_type = MORPH_ELLIPSE; }Mat element = getStructuringElement( erosion_type,Size( 2*erosion_size + 1, 2*erosion_size+1 ),Point( erosion_size, erosion_size ) );/// Apply the erosion operationerode( src, erosion_dst, element );imshow( "Erosion Demo", erosion_dst );
}void Dilation( int, void* )
{int dilation_type = 0;if( dilation_elem == 0 ){ dilation_type = MORPH_RECT; }else if( dilation_elem == 1 ){ dilation_type = MORPH_CROSS; }else if( dilation_elem == 2) { dilation_type = MORPH_ELLIPSE; }Mat element = getStructuringElement( dilation_type,Size( 2*dilation_size + 1, 2*dilation_size+1 ),Point( dilation_size, dilation_size ) );/// Apply the dilation operationdilate( src, dilation_dst, element );imshow( "Dilation Demo", dilation_dst );
}

更改Trackbars的位置就会产生不一样的输出图像

更多的形态学变换

开运算(opening):是通过对图像先腐蚀后膨胀实现  , 能够排除小团块物体(假设物体较背景明亮)

闭运算:(closing):使用过先膨胀后腐蚀实现的,  能够排除小型黑洞(黑色区域)

形态梯度(morphological Gradient):膨胀图与腐蚀图之差 , 能够保留物体的边缘轮廓

顶帽(Top Hat):原图像与开运算结果图之差   

黑帽(black Hat):闭运算结果图与原图像之差

源码

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>using namespace cv;/// Global variables
Mat src, dst;int morph_elem = 0;
int morph_size = 0;
int morph_operator = 0;
int const max_operator = 4;
int const max_elem = 2;
int const max_kernel_size = 21;const char* window_name = "Morphology Transformations Demo";/** Function Headers */
void Morphology_Operations( int, void* );int main( int, char** argv )
{///  载入图像src = imread( argv[1] );if( !src.data ){ return -1; }/// Create windownamedWindow( window_name, WINDOW_AUTOSIZE );/// Create Trackbar to select Morphology operationcreateTrackbar("Operator:\n 0: Opening - 1: Closing  \n 2: Gradient - 3: Top Hat \n 4: Black Hat", window_name, &morph_operator, max_operator, Morphology_Operations );/// Create Trackbar to select kernel typecreateTrackbar( "Element:\n 0: Rect - 1: Cross - 2: Ellipse", window_name,&morph_elem, max_elem,Morphology_Operations );/// Create Trackbar to choose kernel sizecreateTrackbar( "Kernel size:\n 2n +1", window_name,&morph_size, max_kernel_size,Morphology_Operations );/// Default startMorphology_Operations( 0, 0 );waitKey(0);return 0;
}/*** @function Morphology_Operations*/
void Morphology_Operations( int, void* )
{// Since MORPH_X : 2,3,4,5 and 6int operation = morph_operator + 2;Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) );/// Apply the specified morphology operationmorphologyEx( src, dst, operation, element );imshow( window_name, dst );
}

图像处理_imgproc笔记(1)相关推荐

  1. 数字图像处理学习笔记(三):ORB算法(尺度不变特征变换)Oriented FAST and Rotated BRIEF

    数字图像处理学习笔记(三):ORB算法(尺度不变特征变换)Oriented FAST and Rotated BRIEF 一.概述 参考:特征点匹配+特征检测方法汇总 ORB的全称是Oriented ...

  2. 数字图像处理学习笔记(二):SIFT(尺度不变特征变换)算法

    数字图像处理学习笔记(二):SIFT(尺度不变特征变换)算法 一.概述: 提到特征点算法,首先就是大名鼎鼎的SIFT算法了.SIFT的全称是Scale Invariant Feature Transf ...

  3. 数字图像处理学习笔记(一):特征检测和匹配概述

    数字图像处理学习笔记(一):特征检测和匹配概述 参考博客: 特征点的匹配 SIFT特征详解 数字图像处理学习笔记(二):SIFT(尺度不变特征变换)算法 1.特征点概述 如何高效且准确的匹配出两个不同 ...

  4. 数字图像处理学习笔记(三)——空间分辨率和灰度分辨率、等偏爱曲线

    数字图像处理(Digital Image Processing)是通过计算机对图像进行去除噪声.增强.复原.分割.提取特征等处理的方法和技术.本专栏将以学习笔记形式对数字图像处理的重点基础知识进行总结 ...

  5. 基于python的数字图像处理--学习笔记(三)

    基于python的数字图像处理--学习笔记(三) 前言 一.灰度拉伸 二.幂律(伽马)变换 三.对数变换 前言 进入冈萨雷斯的第三章内容,并用python实现功能.我更改了代码源,之前找到太烂了,代码 ...

  6. 数字图像处理学习笔记(十五)——图像复原与重建

    数字图像处理(Digital Image Processing)是通过计算机对图像进行去除噪声.增强.复原.分割.提取特征等处理的方法和技术.本专栏将以学习笔记形式对数字图像处理的重点基础知识进行总结 ...

  7. matlab bwmorph spur,matlab图像处理学习笔记-数学形态与二值图像操作

    matlab图像处理学习笔记-数学形态与二值图像操作 数学形态学主要处理的是二值图像,因为二值图像的处理操作比较简单. 9.1 数学形态学图像处理 基本思想:利用一个称作结构元素(structurin ...

  8. 数字图像处理学习笔记(六)——数字图像处理中用到的数学操作

    数字图像处理(Digital Image Processing)是通过计算机对图像进行去除噪声.增强.复原.分割.提取特征等处理的方法和技术.本专栏将以学习笔记形式对数字图像处理的重点基础知识进行总结 ...

  9. 高光谱图像处理学习笔记

    高光谱图像处理学习笔记 面试需要,所以来学习一下高光谱图像处理的相关知识 文章目录 高光谱图像处理学习笔记 一.高光谱图像相关的概述 一.高光谱图像相关的概述 1.常见的光谱范围 红外光谱范围一般是7 ...

最新文章

  1. BUUCTF(pwn)hgame2018_flag_server(简单的栈溢出)
  2. go数组详解:数组的定义、遍历、使用细节、二维数组的定义及其遍历
  3. 用赫夫曼树进行文件的压缩
  4. 没有bug队——加贝——Python 39,40
  5. mysql 密码文件改成密文_数据库密码弄成密文
  6. Apache Bench
  7. MySQL自定义函数(四十六)
  8. scala编程第17章学习笔记(2)——集和映射
  9. 解决wordpress用户注册时,点击邮件中的重置密码链接提示“您的密码重设链接无效”
  10. matlab得到小波参数,MATLAB|高频信号的小波分析技术要点
  11. Python模块化编程
  12. 2022年CISP考试题库下载
  13. 齐齐哈尔市全国计算机等级考试,2021年9月黑龙江省齐齐哈尔市全国计算机等级考试报名时间...
  14. 厉害了,又一个资源神器
  15. ListView优化机制及滑动时数据时出现的数据错乱重复问题 图片、checkBox等
  16. c语言编计分秒时的程序,用c语言编写程序,用于c51单片机四位共阴数码管显示,显示分秒的计时器。...
  17. getTextSize()和putText()
  18. 了解视图dm_os_performance_counters的cntr_type含义
  19. win10虚拟内存的设置
  20. 三大框架整合步骤(详细)

热门文章

  1. Python Day26:多态、封装、内置函数:__str__、__del__、反射(反省)、动态导入模块...
  2. 使用jdk生成ssl证书文件
  3. 数据结构学习(十三)、快速排序
  4. SER SERVER存储过程
  5. optimize table
  6. Oracle开发:normal ,sysdba,sysoper区别
  7. HDU 1273 漫步森林
  8. DataGridView打印类
  9. C语言程序设计最佳分组,求助把一些数值按指定的和进行分组
  10. android的布局流程,Android View 布局流程(Layout)全面解析