OpenCV图像处理篇之图像平滑
图像平滑算法
图像平滑与图像模糊是同一概念,主要用于图像的去噪。平滑要使用滤波器。为不改变图像的相位信息,一般使用线性滤波器,其统一形式例如以下:
%20\Large%20g(i,j)=\sum_{k,l}f(i+k,j+l)h(k,l)" data-bd-imgshare-binded="1" style="margin: 0px; padding: 0px; border: 0px; max-width: 100%;" alt="" />
当中h称为滤波器的核函数。说白了就是权值。不同的核函数代表不同的滤波器,有不同的用途。
在图像处理中。常见的滤波器包含:
归一化滤波器(Homogeneous blur)
也是均值滤波器,用输出像素点核窗体内的像素均值取代输出点像素值。
高斯滤波器(Guassian blur)
是实际中最经常使用的滤波器。高斯滤波是将输入数组的每个像素点与 高斯内核 卷积将卷积和当作输出像素值。高斯核相当于对输出像素的邻域赋予不同的权值,输出像素点所在位置的权值最大(相应高斯函数的均值位置)。二维高斯函数为,
%20\Large%20G(x,y)%20=%20Ae^{\frac{-(x-u_x)^2}{2\delta_x^2}+\frac{-(y-y_x)^2}{2\delta_y^2}" data-bd-imgshare-binded="1" style="margin: 0px; padding: 0px; border: 0px; max-width: 100%;" alt="" />
中值滤波器(median blur)
中值滤波将图像的每个像素用邻域(以当前像素为中心的正方形区域)像素的中值取代。
对椒盐噪声最有效的滤波器,去除跳变点很有效。
双边滤波器(Bilatrial blur)
为避免滤波器平滑图像去噪的同一时候使边缘也模糊,这样的情况下使用双边滤波器。关于双边滤波器的解释參见http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html
以下的程序将先给标准Lena图像加入椒盐噪声。分别使用4种不同的滤波器进行平滑操作,请注意观察不同滤波器对椒盐噪声的去噪效果。
程序分析及结果
/*
* FileName : image_smoothing.cpp
* Author : xiahouzuoxin @163.com
* Version : v1.0
* Date : Wed 17 Sep 2014 08:30:25 PM CST
* Brief :
*
* Copyright (C) MICL,USTB
*/
#include "cv.h"
#include "imgproc/imgproc.hpp"
#include "highgui/highgui.hpp"
using namespace std;
using namespace cv;
const int MAX_KERNEL_LENGTH = 10;
const char *wn_name = "Smoothing";
static void salt(Mat &I, int n);
static void disp_caption(const char *wn_name, Mat src, const char *caption);
static void disp_image(const char *wn_name, Mat I);
/*
* @brief
* @inputs
* @outputs
* @retval
*/
int main(int argc, char *argv[])
{
if (argc<2) {
cout<<"Usage: ./image_smoothing [file name]"<<endl;
return -1;
}
Mat I = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
salt(I, 6000);
imshow(wn_name, I);
waitKey(0);
Mat dst; // Result
/* Homogeneous blur */
disp_caption(wn_name, I, "Homogeneous blur");
for (int i=1; i<MAX_KERNEL_LENGTH; i+=2) {
blur(I, dst, Size(i, i), Point(-1,-1));
disp_image(wn_name, dst);
}
/* Guassian blur */
disp_caption(wn_name, I, "Gaussian blur");
for (int i=1; i<MAX_KERNEL_LENGTH; i+=2) {
GaussianBlur(I, dst, Size(i, i), 0, 0);
disp_image(wn_name, dst);
}
/* Median blur */
disp_caption(wn_name, I, "Median blur");
for (int i=1; i<MAX_KERNEL_LENGTH; i+=2) {
medianBlur(I, dst, i);
disp_image(wn_name, dst);
}
/* Bilatrial blur */
disp_caption(wn_name, I, "Bilatrial blur");
for (int i=1; i<MAX_KERNEL_LENGTH; i+=2) {
bilateralFilter(I, dst, i, i*2, i/2);
disp_image(wn_name, dst);
}
waitKey(0);
return 0;
}
/*
* @brief 显示提示文字(滤波方法)
* @inputs
* @outputs
* @retval
*/
static void disp_caption(const char *wn_name, Mat src, const char *caption)
{
Mat dst = Mat::zeros(src.size(), src.type());
putText(dst, caption, Point(src.cols/4, src.rows/2), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255,255,255));
imshow(wn_name, dst);
waitKey(0);
}
/*
* @brief 显示图像
* @inputs
* @outputs
* @retval
*/
static void disp_image(const char *wn_name, Mat I)
{
imshow(wn_name, I);
waitKey(1000);
}
/*
* @brief 加入椒盐噪声
* @inputs
* @outputs
* @retval
*/
static void salt(Mat &I, int n=3000)
{
for (int k=0; k<n; k++) {
int i = rand() % I.cols;
int j = rand() % I.rows;
if (I.channels()) {
I.at<uchar>(j,i) = 255;
} else {
I.at<Vec3b>(j,i)[0] = 255;
I.at<Vec3b>(j,i)[1] = 255;
I.at<Vec3b>(j,i)[2] = 255;
}
}
}
上面程序的逻辑很清晰:
读入灰度图,并加入椒盐噪声(6000个噪声点):
Mat I = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
salt(I, 6000);disp_caption和disp_image函数各自是用于显示提示文字和平滑过程中的变化图像的,平滑过程中图像的变化例如以下图:
注意观察上面的图。中值滤波(Median Blur)对椒盐噪声的效果最好!
四种滤波方法分别使用到4个OpenCV函数,这些函数的声明都在
imgproc.hpp中。这些函数的前2个參数都是原图像和滤波后图像。归一化滤波器
blur的第3个參数为滤波核窗体的大小。Size(i,i)表示ixi大小的窗体。高斯滤波器
GaussianBlur第3个參数也是滤波核窗体的大小,第4、第5个參数分辨表示x方向和y方向的δ。中值滤波器
medianBlur第3个參数是滤波器的长度,该滤波器的窗体为正方形。双边滤波器的函数原型例如以下:
//! smooths the image using bilateral filter
CV_EXPORTS_W void bilateralFilter( InputArray src, OutputArray dst, int d,
double sigmaColor, double sigmaSpace,
int borderType=BORDER_DEFAULT );本程序使用的Makefile文件为:
TARG=image_smoothing
SRC=image_smoothing.cpp
LIB=-L/usr/local/lib/
INC=-I/usr/local/include/opencv/ -I/usr/local/include/opencv2
CFLAGS= $(TARG):$(SRC)
g++ -g -o $@ ${CFLAGS} $(LIB) $(INC) \
-lopencv_core -lopencv_highgui -lopencv_imgproc \
$^ .PHONY:clean clean:
-rm $(TARG) tags -f
OpenCV图像处理篇之图像平滑的更多相关文章
- OpenCV图像处理篇之边缘检测算子
OpenCV图像处理篇之边缘检测算子 转载: http://xiahouzuoxin.github.io/notes/ 3种边缘检测算子 一阶导数的梯度算子 高斯拉普拉斯算子 Canny算子 Open ...
- OpenCV图像处理篇之边缘检測算子
3种边缘检測算子 灰度或结构等信息的突变位置是图像的边缘,图像的边缘有幅度和方向属性.沿边缘方向像素变化缓慢,垂直边缘方向像素变化剧烈.因此,边缘上的变化能通过梯度计算出来. 一阶导数的梯度算子 对于 ...
- OpenCV图像处理篇之腐蚀与膨胀
转载请注明出处:http://xiahouzuoxin.github.io/notes 腐蚀与膨胀 腐蚀和膨胀是图像的形态学处理中最主要的操作,之后遇见的开操作和闭操作都是腐蚀和膨胀操作的结合运算. ...
- OpenCV图像处理篇之阈值操作函数
阈值操作类型 这5种阈值操作类型保留opencv tutorials中的英文名称.依次为: Threshold Binary:即二值化,将大于阈值的灰度值设为最大灰度值.小于阈值的值设为0. Thre ...
- OPENCV第一篇
了解过之前老版本OpenCV的童鞋们都应该清楚,对于OpenCV1.0时代的基于 C 语言接口而建的图像存储格式IplImage*,如果在退出前忘记release掉的话,就会照成内存泄露.而且用起来超 ...
- 《OpenCV图像处理编程实例》
<OpenCV图像处理编程实例>例程复现 随书代码下载:http://www.broadview.com.cn/28573 总结+遇到的issue解决: 第一章 初识OpenCV 1.VS ...
- 【OpenCV第一篇】安装OpenCV
[OpenCV第一篇]安装OpenCV 本篇主要介绍如何下载OpenCV安装程序,如何在VS2008下安装配置OpenCV,文章最后还介绍了一个使用OpenCV的简单小例子. <OpenCV入门 ...
- Python+OpenCV图像处理(一)
Python+OpenCV图像处理(一): 读取,写入和展示图片 调用摄像头拍照 调用摄像头录制视频 1. 读取.写入和展示图片 图像读入:cv2.imread() 使用函数cv2.imread() ...
- Python+OpenCV图像处理(一)——读取显示一张图片
先在此处先声明,后面学习python+opencv图像处理时均参考这位博主的博文https://blog.csdn.net/u011321546/article/category/7495016/2? ...
随机推荐
- 牛客noip前集训营(第一场)提高T1
链接:https://www.nowcoder.com/acm/contest/172/A来源:牛客网 题目描述 小N得到了一个非常神奇的序列A.这个序列长度为N,下标从1开始.A的一个子区间对应一个 ...
- UVa-340-猜数字
#include <stdio.h> char ans[1000],gus[1000]; int num[10]; int main() { int n,cnt=1; while (sca ...
- 解决 【xshell 5 不能使用退格键和Delete建】的问题
###按照图片操作即可 1,打开[文件],选择[打开]选项 2.在会话中,打开[属性] 3.点击左边[终端]下的[键盘]选项,按照如下设置 即可.
- 南邮CTF--md5_碰撞
南邮CTF--难题笔记 题目:md5 collision (md5 碰撞) 解析: 经过阅读源码后,发现其代码是要求 a !=b 且 md5(a) == md5(b) 才会显示flag,利用PHP语言 ...
- 07 mongodb
mongodb mongodb简介 简介 MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为Web应用提供可扩展的高性能数据存储解决方案. MongoDB是一个介于关系数据 ...
- LeetCode(73)Set Matrix Zeroes
题目 Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. cli ...
- 【HDU 6006】Engineer Assignment(状压DP)
Problem Description In Google, there are many experts of different areas. For example, MapReduce exp ...
- 【HDU 3037】Saving Beans(卢卡斯模板)
Problem Description Although winter is far away, squirrels have to work day and night to save beans. ...
- sed之h;H和:a;N;ba使用精解(对段落进行操作)
1) 文本: Handle 0x0058, DMI type 20, 19 bytes Memory Device Mapped Address Starting Address: 0 ...
- 使用MyBatista----上传图像
使用MyBatis上传图像,使用的是Oracle的数据库表,有一个TEACHER表,有7列,有1列是存储图片的,类型用BLOB,最大容量是4G,以二进制的形式写入数据库表. 建立这个表的对应实体类Te ...