图像处理 边缘检测 绘制金字塔 模板匹配

第四周学习笔记

1.Canny边缘检测

Canny边缘检测器是一种多步算法,用于检测任何输入图像的边缘。

边缘检测步骤:

1.应用高斯滤波器,以平滑图像,滤除噪声(降噪

2.计算图像中每个像素点的梯度大小(边缘两侧和卷积之间的像素差值和方向(x和y方向)(梯度Scole算子检测边缘)

3.使用非极大值抑制,消除边缘检测带来的不利影响(对于主体的其他一些干扰边缘)

4.应用双阈值检测确定真实和潜在的边缘(比如检测人的边缘的时候,其他物体也有其他边缘,但是我们为了尽力只是提取出人的边缘的时候,我们要弱化孤立的边缘从而完成检测)

5.经历以上步骤,完成检测,打印出边缘图片

为什么使用Canny进行边缘检测?

1.良好的检测:最佳检测器必须消除出现误报(高斯滤波进行处理)和漏报(Scole算子进行处理)的可能性

2.良好的定位:检测到的边缘必须尽可能地接近真实边缘(双阈值检测)

3.单响应约束:检测器必须只为每个边缘点返回一个点(非极大值抑制)

1.应用高斯滤波器,以平滑图像,滤除噪声(进行降噪)

边缘检测易首噪声影响,所以使用高斯滤波器进行平滑图像,降低噪声,因为如果存在噪声期间,像素可能与相邻的像素不接近,这可能会获得不适当甚至是偏离的边缘检测,为了避免这样的情况,我们使用高斯滤波器与图像卷积并去除噪声。

我们将高斯滤波器或者是核g(x,y)与输入图像I进行卷积来降低噪声

2.计算图像中每个像素点的梯度大小和方向(梯度)

在这里我们使用的是Sobel算子得出具有大小的方向的梯度向量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VSE30msW-1685169555045)(C:\Users\86185\Desktop\学习笔记图片\12328b50590b82e440ff86959df1fea1.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rd0rR52g-1685169555046)(C:\Users\86185\Desktop\学习笔记图片\09852a99ed68797344333646fd2f7011.png)]

3.使用非极大值抑制

使用极大值抑制可以使得只为一个像素点返回一个点,我们在沿着边缘的时候,通常观察到有好几个点,这使得边缘的可见性更加清晰,所以我们使用非极大值抑制来忽略那些对特征可见性贡献不大的边缘点。

首先,检测器会遍历图像中所以的像素点,判断当前像素点是否是周围像素点中具有相同方向(角度)梯度的最大值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yym1tuTG-1685169555047)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\569c1f22faa6ad075d905a6838f007e4.jpg)]

在这张图中,同方向(两个或者两个以上)的周围元素都在同一列中,有这相同方向的最大值,就拿第一列来说是7(相同方向都是垂直向上),第二列是8,第三列是9,第四列是6,第五列是5,**保留极大值,其他的像素就置零。**这样就可以抑制那些非极大值的像素点,从而真正只是返回到周围的一个点,使得边缘更加清晰

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gSuc13gJ-1685169555047)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\26a0ee4f9bac12bf476d70e24a429d32.png)]

4.双阈值检测

使用双阈值检测确定真实和潜在的边缘

minVal:最小的阈值

maxVal:最大的阈值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-InNEwLKu-1685169555048)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-22 203745.png)]

如果一个像素的梯度|Gx+Gy|或者是根号下Gx的平方+Gy的平方,在最大的阈值上方那么就声明为"边缘像素",梯度值在最小的阈值和最大的阈值之间如果连接了边界那么就保存下来,如果没有连接的话就舍弃,如果梯度值小于最小的阈值,那么就直接舍弃声明为"非边缘像素"

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dlXeVCq2-1685169555048)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\2023.05.22_23.04.05.jpg)]

如图所示,在maxVal不变的情况下当minVal取得越小的时候,说明原来之前minVal的下方不能作为边界的点的时候,现在却出现在第二个minVal的上方,说明原来不能取得边界的点现在居然可以作为边界,相当于边缘的信息增加了,相当于放松了条件

5.代码实现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qzs5V8aY-1685169555049)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-22 233904.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c6d9YLg4-1685169555050)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-22 234230.png)]

2.图像轮廓

1.什么是图像轮廓?

上面的Canny边缘检测虽然能够精准地检测出边缘,但是边缘是不连续的,检测到的边缘并不是一个整体,图像轮廓是指将边缘连接形成一个整体,用于后续的计算。

图像轮廓是图像中非常重要的一个特征信息,通过对图像轮廓的操作,我们能够获得目标图像的大小,位置,方向等信息。

图像轮廓操作包括:查找轮廓,绘制轮廓,轮廓拟合等

2每个步骤概念

1.查找和绘制轮廓

一个轮廓对应着一系列的点,这些点以某种方式表示图像中的一条曲线,将这些点绘制成不同样式的线条,就是轮廓查找和绘制

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KbgBn5bm-1685169555050)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 083449.png)]

2.轮廓拟合

在计算轮廓的时候,我们可能并不需要实际的轮廓,而是仅仅需要一个接近轮廓的近似多边形,来绘制这个近似多变形的过程叫做轮廓拟合

常见的方法有

矩形包围框

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pg1bhFUM-1685169555051)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 083858.png)]

最小包围面积

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xuw4nteP-1685169555052)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 083910.png)]

最优拟合椭圆

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RGTuBkW3-1685169555053)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 083924.png)]

逼近多边形

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZKcOnbAd-1685169555054)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 084251.png)]

3.轮廓处理实现

OpenCV中提供了查找图像轮廓的函数contour是轮廓的意思 cv2.findContours(),这个函数能够查找图像内的轮廓信息,查找出边缘,而函数cv2.drawContours()能够将轮廓绘制出来。

1查找轮廓

#查找轮廓函数:cv2.findContours()
#语法格式 image,contours,hierarchy=cv2.findContours(image,mode,method)

返回值

image:与函数参数中的原始图像image一致

contours:返回的轮廓。该返回值返回的是一组轮廓信息,每个轮廓都是由若干个点所构成的(每个轮廓为一个list表示)。例如,contours[i]是第i(可能一副图中有多个物体)个轮廓(下标从0开始),contours[i][j]是第i个轮廓内的第j个点

hierarchy:图像的拓扑信息(反映轮廓层次)。图像内的轮廓可能位于不同的位置。比如,一个轮廓在另一个轮廓的内部。在这种情况下,我们将外部的轮廓称为父轮廓,内部的轮廓称为子轮廓。按照上述关系分类,一幅图像中所有轮廓之间就建立了父子关系。每个轮廓contours[i]对应4个元素来说明当前轮廓的层次关系。其形式为:[Next,Previous,First_Child,Parent],分别表示后一个轮廓的索引编号、前一个轮廓的索引编号、第1个子轮廓的索引编号、父轮廓的索引编号,如果没有的话,那么对应的位置就设置为默认值-1

查找轮廓函数的输入参数

image:原始图像。灰度图像会被自动处理为二值图像。在实际操作时,可以根据需要,预先使用阈值处理等函数将待查找轮廓的图像处理为二值图像

mode:轮廓检索模式,有以下取值和含义

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lmm2HDM5-1685169555054)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 090139.png)]

我们一般就是使用第一种cv2.RETR_EXTERAL中的只检测外轮廓

method:轮廓的近似方法,主要有以下取值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O8yGycuL-1685169555055)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 091650.png)]

注意事项:

1:待处理的源图像必须是灰度二值图(在查找轮廓之前利用图像阈值的方法得到)

2.都是从黑色背景中查找白色对象,因此,对象必须是白色的,背景必须是黑色的

3.在 OpenCV 4.X 中,函数 cv2.findContours()仅有两个返回值,其语法格式为 contours, hierarchy = cv2.findContours( image, mode, method)

2.绘制轮廓

#绘制图像:cv2.drawContours()函数
#语法形式:image=cv2.drawContours(image,conours,contouridx,color,thickness)
#参数:
#image:待绘制轮廓的输入图像
#contours:需要绘制的轮廓,该参数的类型与函数cv2.findContours()的输出contours相同,都是list类型
#contourIdx:需要绘制的边缘索引,告诉函数cv2.drawContours()要绘制某一条轮廓还是全部轮廓。如果该参数是一个整数或者为零,则表示绘制对应索引号的轮廓;如果该值为负数(通常为“-1”),则表示绘制全部轮廓。
#color:绘制的颜色,用BGR格式来表示,比如如果是(255,0,0)那么说明绘制出来的轮廓的颜色是蓝色的
#thickness是轮廓的线宽,如果是负值或者CV_FILLED表示填充轮廓内部

3.代码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xszLEu2u-1685169555056)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 195802.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KumUQxl0-1685169555056)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 195907.png)]

#print(type(contours))

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YAtO3G4T-1685169555057)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 200737.png)]

#for contour in contours:
        print(type(contour))
        print(contour.shape)#第一个是长 第二个是高/宽 第三个是颜色通道

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Yq7mDvU-1685169555058)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 201028.png)]

4.轮廓拟合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FKd39OVl-1685169555059)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 203835.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tZQG5l8p-1685169555060)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 203851.png)]

3.模板匹配

1.什么是模板匹配?

模板匹配是指当前图像A(小)内匹配与图像B(大)最相似的地方,一般将图像A(小)称为输入图像,为模板图像。

​ 图像B

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZAt3kQpK-1685169555061)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 205929.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EpWr2WgO-1685169555062)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 205941.png)]

​ 图像A

模板匹配的方法是将模板图像B在A上滑动,方向是从左到右,从上到下进行滑动匹配。

如果输入图像(原始图像)尺寸是W * H,模板的尺寸是w * h,则返回值的大小为(W-w+1)*(H-h+1)。

在进行模板匹配时,模板在原始图像内遍历。在水平方向上:

遍历的起始坐标是原始图像左数第1个像素值(序号从1开始)。
最后一次比较是当模板图像位于原始图像的最右侧时,此时其左上角像素点所在的位置是W-w+1。
因此,返回值result在水平方向上的大小是W-w+1(水平方向上的比较次数)。

在垂直方向上:

遍历的起始坐标从原始图像顶端的第1个像素开始。
最后一次比较是当模板图像位于原始图像的最下端时,此时其左上角像素点所在位置是H-h+1。
所以,返回值result在垂直方向上的大小是H-h+1(垂直方向上的比较次数)。

如果原始图像尺寸是 W * H,模板的尺寸是w * h,则返回值的大小为(W-w+1)* (H-h+1)。也就是说,模板图像要在输入图像内比较(W-w+1)*(H-h+1)次。

模板匹配和卷积原理很像,模板在原图像从原点开始从左到右,从上到下开始滑动,计算模板与(图像中被模板覆盖的地方的差别程度),逐个像素遍历整幅输入图像,以查找与其最匹配的地方。这个差别程度的计算方法在OpenCV中有六种方法,选择其中的方法进行把每次计算的结果放在一个矩阵中,作为结果输出,假如原图像是AB大小,而模板是ab大小,那么输出的结果矩阵是(A-a+1)(B-b+1)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-STJKNYRD-1685169555063)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 214823.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8YEvKAkg-1685169555064)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 215641.png)]

2.模板匹配图像

​ #匹配 模板

在Opencv中,通过函数cv2.matchTemplate()进行模板匹配。语法格式:

#result=cv2.matchTemplate(image,templ,method)
#result是输出图像
#image是原始图像
#templ是模板图像,他的尺寸必须小于或者等于原始图像,并且与原始图像具有同样的类型
#method是匹配方法,有六种可能的值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b3jVqvXV-1685169555065)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 214211.png)]

​ 具体计算的公式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sXiukf8i-1685169555066)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 214252.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OfPttHGy-1685169555067)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 214558.png)]

3.查找最值

#minVal,maxVal,minLoc,maxLoc=cv2.minMaxLoc(src[,mask])
#src:为单通道数组。
#minVal:为返回的最小值,如果没有最小值,则可以是NULL(空值)。
#maxVal:为返回的最大值,如果没有最小值,则可以是NULL。
#minLoc:为最大值的位置,如果没有最大值,则可以是NULL。
#maxLoc:为最大值的位置,如果没有最大值,则可以是NULL。
#mask:为用来选取掩模的子集,可选项

综上所述,函数cv2.matchTemplate()返回值中的最值位置就是模板匹配的位置。

例如,当method的值为cv2.TM_SQDIFF和cv2.TM_SQDIFF_NORMED时,0表示最佳匹配,值越大,则表示匹配效果越差。当使用这两种方法时,要寻找最小值所在的位置作为最佳匹配。如下语句能够找到cv2.matchTemplate()函数返回值中最小值的位置:

minVal,maxVal,minLoc,maxLoc=cv2.minMaxLoc(matchTemplate函数的返回值)

topLeft=minLoc # 查找最小值所在的位置

以topLeft点为模板匹配位置的左上角坐标,结合模板图像的宽度w和高度h可以确定匹配位置的右下角坐标,代码如下所示:

bottomRight=(topLeft[0]+w,topLeft[1]+h)  #w和h是模板图像的宽度和高度
当 method 的值为 cv2.TM_CCORR、cv2.TM_CCORR_NORMED、cv2.TM_CCOEFF 和cv2.TM_CCOEFF_NORMED时,cv2.matchTemplate()函数的返回值越小,表示匹配度越差,而返回值越大则表示匹配度越好。此时,要寻找最大值所在的位置作为最佳匹配。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V1BD4Jmz-1685169555068)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 221218.png)]

这张图,利用不同的模板匹配的计算方法得到最大值或者是最小值都然后在图像中确定出匹配度最高的位置

4.绘制出最佳匹配模板

#函数cv2.rectangle的语法格式为:
#img=cv.rectangle(img,pt1,pt2,color,thickness)
#img:表示要标记的目标图像。
#pt1:是矩形的顶点。
#pt2:是pt1的对角顶点。
#color:是要绘制矩形的颜色或灰度级(灰度图像)。
#thickness:是矩形边线的宽度

5.单模板匹配代码实现

import cv2 as cv
import matplotlib.pyplot as plt
#模板匹配
img=cv.imread("img.png",0)#读取原图像
temp=cv.imread("temp.png",0)#读取模板图像
w,h=temp.shape#灰度图只有两个返回结果
#print(img.shape)
#print(temp.shape)
methods=['cv.TM_CCOEFF','cv.TM_CCOEFF_NORMED','cv.TM_CCORR','cv.TM_CCORR_NORMED','cv.TM_SQDIFF','cv.TM_SQDIFF_NORMED']
for meth in methods:
    img2=img.copy()
    method=eval(meth)#不能传入字符串,使用eval()返回传入字符串的表达式的结果。就是说:将字符串当成有效的表达式 来求值并返回计算结果。
    #对每一种模板匹配方法进行计算
    res=cv.matchTemplate(img,temp,method)#返回输出图像
    #查找最值
    minVal,maxVal,minLoc,maxLoc=cv.minMaxLoc(res)#返回最匹配的图像的最值
    if method in[cv.TM_SQDIFF,cv.TM_SQDIFF_NORMED]:
        top_left=minLoc
    else:
        top_left=maxLoc
    bottom_right=(top_left[0]+w,top_left[1]+h)
    #画矩形
    res2=cv.rectangle(img2,top_left,bottom_right,(255,0,0),1)
    plt.subplot(121),plt.imshow(res,'gray')
    plt.xticks([]),plt.yticks([])
    plt.subplot(122),plt.imshow(res2,'gray')
    plt.xticks([]),plt.yticks([])
    plt.suptitle(meth)
    plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2p3EwCWQ-1685169555068)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\Figure_1.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XfU1z9hI-1685169555070)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\Figure_2.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iBCboU4n-1685169555070)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\Figure_3png.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YGodMUja-1685169555071)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\Figure_4.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CpOy4ZzX-1685169555071)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\Figure_5.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PuQi0v82-1685169555072)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\Figure_6.png)]

4.图像金字塔

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mabotkG9-1685169555073)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-23 235523.png)]

1.什么是图像金字塔?

图像金字塔是由一幅图像的多个不同分辨率的子图构成的图像集合。是通过一个图像不断的降低采样率产生的,最小的图像可能仅仅有一个像素点。

这是一个图像金子塔的示例。从图中可以看到,图像金字塔是一系列以金字塔形状排列的、自底向上分辨率逐渐降低的图像集合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LgvDpGls-1685169555074)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\e04e0ea8b87b4df1919621df3cb60994 (2)].png)

通常情况下,图像金字塔的底部是待处理的高分辨率图像(原始图像),而顶部则为其低分辨率的近似图像。向金字塔顶部移动时,图像的尺寸和分辨率都不断地降低。通常情况下,每向上移动一级,图像的宽和高都降低为原来的二分之一

2.向下采样

最简单的图像金字塔可以通过不断的删除图像的偶数行和偶数列得到的。例如,有一幅图像,其大小是NN,删除其偶数行和偶数列后得到一幅(N/2)(N/2)大小的图像。经过上述处理后,图像的大小变为原来的四分之一,不断重复该过程,就可以得到该图像的图像金字塔。

也可以通过先对原始图像滤波,得到原始图像的近似图像,然后将近似图像的偶数行和偶数列删除以获取向下采样的结果。有多种滤波器可以选择。

高斯滤波器:采用高斯滤波器对原始图像进行滤波,得到高斯金字塔。这是OpenCV函数cv2.pyrDown()所采用的的方式。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d54Xg2Pe-1685169555074)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\22c3b4fb208440361b9a8220fabfa967.png)]

3.向上采样

在向上采样的过程中,通常将图像的宽度和高度都变为原来的2倍。这意味着,向上采样的结果图像的大小是原始图像的4倍。因此,要在结果图像中补充大量的像素点。对新生成的像素点进行赋值的行为,称为 插值。该过程可以通过多种方式实现,例如最邻近插值就是使用最邻近的像素点给当前还没有值的像素点赋值。

在opencv中的插值方法是,对像素点以补零的方式完成插值。通常是在每列像素点的右侧插入值为零的列,在每行像素点的下方插入值为零的行。如图,左侧是要进行向上采样的4个像素点,右侧是向上采样时进行补零后处理结果。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cOsQCwKa-1685169555075)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\50ddfd1b22d068f133fcf433b44ea661.png)]

接下来,使用向下采样时所使用的的高斯滤波器对补零后的图像进行滤波处理,以获取向上采样的结果图像。 但是需要注意,此时图像中有四分之三的像素点的值都是零。所以,要将高斯滤波器系数乘以4,以保证得到的像素值在其原有像素值的范围内。

通过以上分析可知,向上采样和向下采样是相反的两种操作。但是,由于上下采样会丢失像素值,所以两种操作并不是可逆的。 也就是说,对一幅图像先向上采样、再向下采样,是无法恢复期原始状态的;同样,对一幅图像先向下采样、再向上采样也是无法恢复到原始状态的。

4.函数解析

cv2.pyrDown()函数首先对原始图像进行高斯滤波变换,以获取原始图像的近似图像。在获取近似图像后,该函数通过抛弃偶数行和偶数列来实现向下采样

在使用cv2.pyrUp()函数对图像向上采样时,在每个像素的右侧、下方分别插入零值列和零值行,得到一个偶数行、偶数列(即新增的行、列)都是零值的新图像New。接下来,用向下采样时所使用的高斯滤波器对新图像New进行滤波,得到向上采样的结果图像。需要注意的是,为了确保像素值的区间在向上采样后与原始图像保持一致,需要将高斯滤波器的系数乘以4。

5.代码实现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qO4R6XMa-1685169555076)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-24 004901.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KBfu8oR2-1685169555076)(C:\Users\86185\AppData\Roaming\Typora\draftsRecover\屏幕截图 2023-05-24 005003.png)]

其他同理
先向下采样、再向上采样也是无法恢复到原始状态的。

4.函数解析

cv2.pyrDown()函数首先对原始图像进行高斯滤波变换,以获取原始图像的近似图像。在获取近似图像后,该函数通过抛弃偶数行和偶数列来实现向下采样

在使用cv2.pyrUp()函数对图像向上采样时,在每个像素的右侧、下方分别插入零值列和零值行,得到一个偶数行、偶数列(即新增的行、列)都是零值的新图像New。接下来,用向下采样时所使用的高斯滤波器对新图像New进行滤波,得到向上采样的结果图像。需要注意的是,为了确保像素值的区间在向上采样后与原始图像保持一致,需要将高斯滤波器的系数乘以4。

5.代码实现

[外链图片转存中…(img-qO4R6XMa-1685169555076)]

[外链图片转存中…(img-KBfu8oR2-1685169555076)]

其他同理

你可能感兴趣的:(图像处理,计算机视觉,深度学习)