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? ...
随机推荐
- css控制超出部分自动省略...
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- luogu P1042 乒乓球
题目背景 国际乒联现在主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及.其中11分制改革引起了很大的争议,有一部分球员因为无法适应新规则只能选择退役.华华就是其中一位,他退役 ...
- vue 运行时 + 编译器 vs. 只包含运行时
https://cn.vuejs.org/v2/guide/installation.html#运行时-编译器-vs-只包含运行时 文档中的这个地方,说的不清楚 If you need to comp ...
- 如何学好C++语言(转)
不久前发现陈皓的blog -- 酷壳,闲暇之余看看,学到不少东西,感觉作为一个程序员自己才刚开始也还有很长的路需要去走.真后悔本科到研究生的6年间看书不够,那只有从现在起不断的学习.最近有李开复老师得 ...
- Python通过Openpyxl包汇总表格,效率提升100倍
最近找了份小兼职,干的全是些无聊的工作,比如说给word调整一下排版啦.把从多方回收来的Excel汇总啦,这些极其催眠又耗时的事,怎么能接受手动去做呢!!(疯了嘛,谁知道以后还有多少类似的表格要汇总啊 ...
- Problem 2125 简单的等式(FZU),,数学题。。。
Problem 2125 简单的等式 Time Limit: 1000 mSec Memory Limit : 32768 KB Problem Description 现在有一个等式如下:x^2+ ...
- POJ 1080 Human Gene Functions 【dp】
题目大意:每次给出两个碱基序列(包含ATGC的两个字符串),其中每一个碱基与另一串中碱基如果配对或者与空串对应会有一个分数(可能为负),找出一种方式使得两个序列配对的分数最大 思路:字符串动态规划的经 ...
- bzoj 1703 [Usaco2007 奶牛排名 传递闭包
[Usaco2007 Mar]Ranking the Cows 奶牛排名 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 504 Solved: 343[ ...
- 推荐一个 Java 实体映射工具 MapStruct
声明: 1.DO(业务实体对象),DTO(数据传输对象). 2.我的代码中用到了 Lombok ,不了解的可以自行了解一下,了解的忽略这条就好. 在一个成熟的工程中,尤其是现在的分布式系统中,应用与应 ...
- Codevs 队列练习 合并版
3185 队列练习 1 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 给定一个队列(初始为空),只有两种操作入队和出队,现给出这 ...