【读书】《计算机视觉之PyTorch数字图像处理》4.特征点提取
[复制链接]
本帖最后由 waterman 于 2024-12-2 12:07 编辑
在图像处理中最重要的一步就是从图像中提取关键信息。例如:在图像匹配环节,提取图像特征点是第一步也是最重要的一步;在各种形状的提取环节,准确检测边缘时至关重要的。在图像处理研究中,图像的信息一般主要集中在少数像素中,这些像素通过构成点、线和面来反映图像的关键信息。因此寻找图像的点、线和面特征时图像处理的一个基本问题。本章将根据书中的内容学习使用pytorch进行特征点提取。
特征点
图像特征点也成为关键点(Keypoint),其提取方法是计算机视觉中的一个基本问题。
通常一种特征点提取算法既包括对特征点的提取,又包括其对应描述子的计算,但也可以将两者进行分离,将不同的特征点提取方法与不同的特征点描述子相组合。
Harris角点检测算法是最早提出的图像特征点检测的方法之一,他是针对灰度图提出的,并取得了较好的效果。该方法提取的角点较为稳定,是一种经典的特征点检测方法。
代码实战
我们以本书的宣传页为例,进行特征点提取。
利用Pytorch进行Harris角点提取的过程具体如下:
-
导入相应的处理库并打开要处理的图像。
from PIL import Image #导入图像读、存储库
from torchvision import transforms #导入图像,张量变换库
import torch.nn.functional as F #导入张量计算函数,起别名为F
import torch as tc #导入PyTorch库,并起别名tc
img=Image.open('./1.png') #打开图像
#img = img.resize((500,300))
-
将图像转换为灰度图,并且将图像转换为张量。
img=img.convert('L') #将图像转为灰度图
imgtensor=transforms.ToTensor()(img) #将图像格式转为PyTorch的3维张量类型
-
利用torch.nn.functional.conv2d()函数完成Dx和Dy的计算。并进一步得到Dx^2\Dy^2和Dx*Dy。
imgtensor=imgtensor.unsqueeze(0) #调整张量的维度为nxcxhxw
imgtensor=imgtensor.to('cuda') #送到GPU,如没有GPU可以删除此行,使用CPU
dx=F.conv2d(imgtensor,weight=tc.Tensor([[[[-1,0,1]]]]),stride=1,padding=(0,1)) #计算dx
dy=F.conv2d(imgtensor,weight=tc.Tensor([[[[-1],[0],[1]]]]),stride=1,padding=(1,0)) #计算dy
dx2=dx*dx #Dx2
dy2=dy*dy #Dy2
dxy=dx*dy #Dx×Dy
-
生成高斯分布的卷积核,并对上一步得到的梯度图进行卷积操作从而降低噪声的影响。
def guassmask(imgwidth=51,imgheight=51,sigma=2):
#产生一个宽为imgwidth,高为imgheight的guass核,方差为sigma
#imgheight和imgwidth应为奇数
cx=imgwidth//2
cy=imgheight//2
ypos,xpos=tc.meshgrid([tc.arange(-cy,cy+1),tc.arange(-cx,cx+1)])
return tc.exp(-(xpos**2+ypos**2)/(sigma*sigma))
n=7
gs=guassmask(n,n)
gs=gs/gs.sum() #归一化
gs=gs.unsqueeze(0).unsqueeze(0) #调整维度
A=F.conv2d(dx2,weight=gs,stride=1,padding=n//2)
B=F.conv2d(dy2,weight=gs,stride=1,padding=n//2)
C=F.conv2d(dxy,weight=gs,stride=1,padding=n//2) #进行高斯核卷积,去除不稳定噪声
-
根据计算得到的A、B和C分别计算Tr、Det及R,并设定R的阈值,将值大于0.003的置为特征点。
Tr=A+B
Det=A*B-C*C
R=Det-0.03*Tr*Tr
R=F.relu(R-0.003)
-
将经过阈值化的检测结果进行保存。
mr=255/R.max()
R=R*mr #调整灰度范围
resimg=transforms.ToPILImage('L')(R.squeeze(0)) #把tensor转换回灰度图
resimg.save('./tmp.png') #保存检测结果
第一张是对原图进行特征点提取的结果,由于图像太大的原因可能看不太清楚。第二张图片是原图放缩置500*300后进行特征点提取的结果。
可以看到结果基本正确。
|