OpenCV学习笔记二

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

OpenCV学习笔记(二)
五形态学操作
形态学操作
简单来讲,形态学操作就是基于形状的一系列图像处理操作。

通过将结构元素作用于输入图像来产生输出图像。

最基本的形态学操作有二:腐蚀与膨胀(Erosion 与Dilation)。

他们的运用广泛:
消除噪声
分割(isolate)独立的图像元素,以及连接(join)相邻的元素。

寻找图像中的明显的极大值区域或极小值区域。

腐蚀操作
腐蚀在形态学操作家族里是膨胀操作的孪生姐妹。

它提取的是内核覆盖下的相素最小值。

进行腐蚀操作时,将内核B 划过图像,将内核B 覆盖区域的最小相素值提取,并代替锚点位置的相素。

我们使用腐蚀操作。

从下面的结果图我们看到亮区(背景)变细,而黑色区域(字母)则变大了。

腐蚀操作函数原型:
void erode(InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue() )
1
可以看到前三个是必要的参数,后面都有默认的参数。

InputArray kernel腐蚀操作的内核
膨胀操作
此操作将图像A 与任意形状的内核(B),通常为正方形或圆形,进行卷积。

内核B 有一个可定义的锚点, 通常定义为内核中心点。

进行膨胀操作时,将内核B 划过图像,将内核B 覆盖区域的最大相素值提取,并代替锚点位置的相素。

显然,这一最大化操作将会导致图像中的亮区开始”扩展”(因此有了术语膨胀dilation )
void dilate(InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue() )
1
2
开运算(Opening)
开运算是通过先对图像腐蚀再膨胀实现的。

dst = open( src, element) = dilate( erode( src, element ) )
能够排除小团块物体(假设物体较背景明亮)
闭运算(Closing)
闭运算是通过先对图像膨胀再腐蚀实现的。

dst = close( src, element ) = erode( dilate( src, element ) )
能够排除小型黑洞(黑色区域)。

形态梯度(Morphological Gradient)
膨胀图与腐蚀图之差
dst = morph_{grad}( src, element ) = dilate( src, element ) - erode( src, element
顶帽(Top Hat)
原图像与开运算结果图之差
dst = tophat( src, element ) = src - open( src, element )
黑帽(Black Hat)
闭运算结果图与原图像之差
dst = blackhat( src, element ) = close( src, element ) – src
六图像的放大和缩小
图像金字塔(Image Pyramids)
一个图像金字塔是一系列图像的集合- 所有图像来源于同一张原始图像- 通过梯次向下采样获得,直到达到某个终止条件才停止采样。

有两种类型的图像金字塔常常出现在文献和应用中:
高斯金字塔(Gaussian pyramid): 用来向下采样
拉普拉斯金字塔(Laplacian pyramid): 用来从金字塔低层图像重建上层未采样图像
向下采样导致了,图像放大,造成模糊
向上采样会导致丢失信息,因为他缩小了图像
向上采用函数原型:
void pyrUp(InputArray src, OutputArray dst, const Size& dstsize=Size(), int borderType=BORDER_DEFAULT )
向下采用函数原型:
void pyrDown(InputArray src, OutputArray dst, const Size& dstsize=Size(), int borderType=BORDER_DEFAULT )
实例:
//将图像放大两倍
pyrUp(src, dst, Size(src.cols * 2, src.rows * 2));
//缩小两倍
pyrDown(src, dst, Size(src.cols / 2, src.rows / 2));
七图像修复
图像修复
图像的修复是重建图像和视频受损部分的过程,这个过程也成为图像或视频的插值。

OpenCV 2.4版本支持一种修复算法,函数的模型为:
void inpaint(InputArray src, InputArray inpaintMask, OutputArray dst, double inpaintRadius, int flags)
Parameters:
src : 输入的图像8-bit 1通道或3通道
inpaintMask :图像的掩码, 8-bit 1-channel image.
dst : 输出图像
inpaintRadius:表示有flags所制定的算法可以使用的邻域
flag : 有两种方式
1.INPAINT_NS: 该方法是基于Navier-Stokes方法
2.INPAINT_TELEA: 该方法是抑郁Alexandru Telea提出的算法
如果不知道图像的掩码,则去获得它的掩码挺复杂的,应该你并不知道,什么情况下才是最
优的,只能去实验。

更具阈值去获得图像掩码:
double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type)
其中thresh为所要设置的阈值
maxval为
type 以什么形式设置阈值。

type的方式如下图所示:
这里选用的是二值的方式,即当src(x,y)>thresh时,将其设为maxval.
一个实例:这个例子中获得的不是很好的掩码,掩码的选择可能更为的复杂。

#include "opencv2/opencv.hpp"
#include<iostream>
#include<iomanip>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
// Read the source file
Mat src;
src = imread("3.jpg");
// Create the mask
Mat mask;
cvtColor(src, mask, COLOR_RGB2GRAY); //将其转换成灰度图像,因为掩码必须是一维的
/*for (int i = 0; i < mask.rows; i++) {
for (int j = 0; j < mask.cols; j++)
cout << int(mask.at<uchar>(i, j)) << setw(4);
cout << endl;
}*/
cout << int(mask.at<uchar>(mask.rows/2, mask.cols/2))<<endl;
threshold(mask, mask, 190, 255, THRESH_BINARY);
// Apply the inpainting algorithms
Mat dst, dst2;
inpaint(src, mask, dst, 10, INPAINT_TELEA);
inpaint(src, mask, dst2, 10, INPAINT_NS);
// Show the results
namedWindow(" ORIGINAL ", WINDOW_AUTOSIZE);
imshow(" ORIGINAL ", src);
namedWindow(" MASK ", WINDOW_AUTOSIZE);
imshow(" MASK ", mask);
namedWindow(" INPAINT_TELEA ", WINDOW_AUTOSIZE);
imshow(" INPAINT_TELEA ", dst);
namedWindow(" INPAINT_NS ", WINDOW_AUTOSIZE);
imshow(" INPAINT_NS ", dst2);
waitKey();
return 0;。

相关文档
最新文档