如何解决如何证明高斯金字塔的脉冲响应是尺度不变的? 代码:
我从512x512
图像中建立了一个高斯金字塔,中心有一个狄拉克脉冲(256,256),然后尝试按照以下过程证明该金字塔是尺度不变的,并且具有相同的脉冲每个级别的响应,但结果似乎不太正确!
编辑:
感谢@ CrisLuengo的注释,我编辑了代码以修复一些错误。
代码:
import numpy as np
import matplotlib.pyplot as plt
import cv2
import skimage.exposure as exposure
from math import sqrt,ceil
#=================
# Resize Function
#=================
def _resize(image,downscale=2,step=0.5,minSize=(7,7)):
if(image.shape > minSize ):
# newSize = (image.shape[0]// downscale,image.shape[1]//downscale)
# newImage = cv2.resize(image,dsize=newSize,fx=step,fy=step)
newImage = cv2.resize(image,None,fy=step)
return newImage
else:
return 0
#--------------------------------------------------------------
#===========================
# Gaussian Pyramid Function
#===========================
def pyramid(image,sigma_0=1):
'''
Function to create a Gaussian pyramid from an image for given standard deviation sigma_0
Parameters:
-----------
@param: image: nd-array.
The original image.
@param: sigma_0: float.
standard deviation of the Gaussian distribution.
returns:
List of images with different scales,the pyramid
'''
# Resize All input images into a standard size
image = cv2.resize(image,(512,512))
# level 0
if ceil(6*sigma_0)%2 ==0 :
Gimage = cv2.GaussianBlur(image,(ceil(6*sigma_0)+1,ceil(6*sigma_0)+1),sigmaX=sigma_0,sigmaY=sigma_0)
else:
Gimage = cv2.GaussianBlur(image,(ceil(6*sigma_0)+2,ceil(6*sigma_0)+2),sigmaY=sigma_0)
# sigma_k
sigma_k = 4*sigma_0
# sigma_k = sqrt(2)*sigma_0
# Pyramid as list
Gausspyr = [Gimage]
# Loop of other levels of the pyramid
for k in range(1,6):
if ceil(6*sigma_k)%2 ==0 :
# smoothed = cv2.GaussianBlur(Gausspyr[k-1],(ceil(6*sigma_k)+1,ceil(6*sigma_k)+1),sigmaX=sigma_k,sigmaY=sigma_0)
smoothed = cv2.GaussianBlur(Gausspyr[k-1],sigmaY=sigma_k)
else:
# smoothed = cv2.GaussianBlur(Gausspyr[k-1],(ceil(6*sigma_k)+2,ceil(6*sigma_k)+2),sigmaY=sigma_k)
# Downscaled Image
resized = _resize(smoothed ) #,step=0.25*sigma_k
Gausspyr.append(resized)
return Gausspyr
#====================
# Impulse Response
#====================
# Zeros 512x512 Black Image
delta = np.zeros((512,512),dtype=np.float32)
# Dirac
delta[255,255] = 255
# sigmas
sigma1 = 1
sigma2 = sqrt(2)
# Pyramids
deltaPyramid1 = pyramid(delta,sigma_0=sigma1)
deltaPyramid2 = pyramid(delta,sigma_0=sigma2)
# Impulse Response for each level
ImpResp1 = np.zeros((len(deltaPyramid1),13),dtype=float)
ImpResp2 = np.zeros((len(deltaPyramid2),dtype=float)
# sigma = 1
for idx,level in enumerate(deltaPyramid1):
# # 1
# level = cv2.resize(level,512))#,interpolation=cv2.INTER_AREA
# ImpResp1[idx,:] = exposure.rescale_intensity(level[255,249:262],in_range='image',out_range=(0,255)).astype(np.uint8)
# ImpResp1[idx,:] = level[255,249:262]
# # 2
centery = level.shape[0]//2
centerx = level.shape[1]//2
ImpResp1[idx,:] = exposure.rescale_intensity(level[centery,(centerx-7):(centerx+6)],255),in_range='image').astype(np.uint8)
# ImpResp1[idx,:] = level[centery,(centerx-7):(centerx+6)]
# sigma = sqrt(2)
for idx,level in enumerate(deltaPyramid2):
# # 1
# level = cv2.resize(level,interpolation=cv2.INTER_AREA
# ImpResp2[idx,255)).astype(np.uint8)
# ImpResp2[idx,249:262]
# # 2
centery = level.shape[0]//2
centerx = level.shape[1]//2
ImpResp2[idx,in_range='image').astype(np.uint8)
# ImpResp2[idx,(centerx-7):(centerx+6)]
#====================
# Visualize Results
#====================
labels = []
for c in range(13):
label = 'C{}'.format(c+1)
labels.append(label)
x = np.arange(len(labels)) # the label locations
width = 0.1 # the width of the bars
fig,ax = plt.subplots()
rects1 = []
for k in range(ImpResp1.shape[0]):
rects1.append(ax.bar(x - 2*k*width,ImpResp1[k],width,label='K{}'.format(k)))
# Add some text for labels,title and custom x-axis tick labels,etc.
ax.set_ylabel('values')
ax.set_title('sigma0=1')
ax.set_xticks(x)
ax.set_xticklabels(labels)
ax.legend()
fig.tight_layout()
fig2,ax2 = plt.subplots()
rects2 = []
for k in range(ImpResp1.shape[0]):
rects2.append(ax2.bar(x + 2*k*width,ImpResp2[k],etc.
ax2.set_ylabel('values')
ax2.set_title('sigma0=sqrt(2)')
ax2.set_xticks(x)
ax2.set_xticklabels(labels)
ax2.legend()
fig2.tight_layout()
plt.show()
解决方法
首先,我们将其简化为一种足够简单的情况,以查看高斯的比例属性。将增量图像与高斯卷积会产生高斯。高斯B的大小是高斯A的两倍,然后在空间上缩放一半,与A相同(当然,强度缩放最高,B在2D中是A的1/4)。
delta = <all zeros except one pixel in the middle>
A = GaussianBlur(delta,1)
B = GaussianBlur(delta,2)
B = resize(B,1/2)
A == B * 2**2
C = GaussianBlur(delta,sigma=7.489)
C = resize(C,1/7.489)
A == C * 7.489**2
现在,如果我们链接模糊操作,我们将获得更强的模糊效果。输出总和的平方等于所应用总和的平方和:
A = GaussianBlur(delta,2)
C = GaussianBlur(A,sqrt(3))
B == C
即1**2 + sqrt(3)**2 = 2**2
。
因此,在金字塔的每个步骤中,我们需要计算已经应用的模糊程度,然后应用适当的数量以达到必要的模糊程度。每次模糊时,我们都将模糊增加给定量,每次重新缩放时,我们都将模糊减少给定量。
如果sigma0
是初始平滑,而sigma1
是在缩小之前应用的平滑,并且缩小系数k> 1,则此关系为:
sqrt(sigma0**2 + sigma1**2) / k == sigma0
将确保缩小的增量图像与原始平滑的增量图像相同(直至强度缩放)。我们获得:
sigma1 = sqrt((sigma0 * k)**2 - sigma0**2)
(如果我做对了,请在手机屏幕上显示)。
由于我们返回的图像与原始图像相同,因此后续的金字塔等级将使用这些相同的值。
我在您的代码中注意到的另一个问题是,您在开始处理之前将增量图像重新缩放为“标准大小”。请勿执行此操作,增量图片将不再是增量图片,并且上述关系也将不再成立。输入必须恰好将一个像素设置为1,其余像素设置为0。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。