【干货】计算机视觉实战系列09——用Python做图像处理

2018 年 5 月 15 日 专知 Hui

【导读】通过之前的学习,我们已经熟悉了python关于图像处理的基本操作和工具库,接下来我们将系统学习局部图像的描述子。这一阶段的学习旨在寻找图像间的对应点和对应区域。图像处理的很多内容都会用到局部特征,局部特征在很多应用中都有着重要的作用,比如创建全景图、增强现实技术以及计算图像的三维重建。


【干货】计算机视觉实战系列01——用Python做图像处理(基本的图像操作和处理)

【干货】计算机视觉实战系列02——用Python做图像处理(Matplotlib基本的图像操作和处理)

【干货】计算机视觉实战系列03——用Python做图像处理(Numpy基本操作和图像灰度变换)

【干货】计算机视觉实战系列04——用Python做图像处理(图像的缩放、均匀操作和直方图均衡化)

【干货】计算机视觉实战系列05——用Python做图像处理(主成分分析)

【干货】计算机视觉实战系列06——用Python做图像处理(图像高斯模糊分析)

【干货】计算机视觉实战系列07——用Python做图像处理(SciPy库的应用——图像导数实战)

【干货】计算机视觉实战系列08——用Python做图像处理



Harris角点检测器


Harris角点检测算法,(又称Harris&Stephens角点检测器)是极为简单的一种角点检测算法,该算法的主要思想是:如果某点存在多于一个方向的边,则认为该点是兴趣点,称为角点。算法基本思想是使用一个固定窗口在图像上进行任意方向上的滑动,比较滑动前与滑动后两种情况,窗口中的像素灰度变化程度,如果存在任意方向上的滑动,都有着较大灰度变化,那么我们可以认为该窗口中存在角点。


角点通常被定义为两条边的交点,更严格的说,角点的局部邻域应该具有两个不同区域的不同方向的边界。而实际应用中,大多数所谓的角点检测方法检测的是拥有特定特征的图像点,而不仅仅是“角点”。这些特征点在图像中有具体的坐标,并具有某些数学特征,如局部最大或最小灰度、某些梯度特征等。

 

算法的数学原理




我们将图像上某点x上对称的半定矩阵定义为:


其中为包含方向导数的梯度(在之前的学习中我们 已经详细介绍了方向导数和梯度),由于该定义,的秩为1,特征值为。现在对于图像的每一个像素,我们可以计算出该矩阵。

 

选择权重矩阵W(通常为高斯滤波器),我们可以得到卷积


该卷积的目的是得到在周围像素上的局部平均。计算出的矩阵又称为Harris矩阵,W的宽度决定了像素x周围的感兴趣区域。像这样在区域附近对矩阵取平均的原因是,特征值会依赖于局部图像特征而变化。如果图像的梯度在该区域变化,那么的第二个特征值将不再为0,如果图像的梯度没有变化,的特征值也不会变化。

 

取决于该区域的的值,Harris矩阵的特征值有三种情况:

1. 如果都是很大的正数,则x点为角点;

2. 如果很大,,则该区域内存在一个边,该区域内的平均的特征值不会变化太大;

3. 如果,该区域内为空。

在不需要实际计算特征值的情况下,为了把重要的情况和其他情况分开,Harris和Stephens引入了指示函数


为了去除加权平均常数k,我们通常使用商数作为指示器。


代码




完整的代码如下:

from PIL import Image
import numpy as np
from pylab import *
from scipy.ndimage import filters


def compute_harris_response(im, sigma=3):
'''''
   对每个像素值计算Harris角点检测器响应函数
   :param im:
   :param sigma:
   :return:
   '''

   
# 计算导数  
   
im_x = np.zeros(im.shape)
im_y = np.zeros(im.shape)
filters.gaussian_filter(im, (sigma, sigma), (0, 1), im_x)
filters.gaussian_filter(im, (sigma, sigma), (1, 0), im_y)

# 计算Harris矩阵分量  
   
Ixx = filters.gaussian_filter(im_x * im_x, sigma)
Ixy = filters.gaussian_filter(im_x * im_y, sigma)
Iyy = filters.gaussian_filter(im_y * im_y, sigma)

# 计算特征值和迹  
   
Idet = Ixx * Iyy - Ixy ** 2
   
Itrace = Ixx + Iyy

result = Idet / Itrace
result[isnan(result)] = 0
   
return result


def get_harris_points(harrisim, min_dist=10, threshold=0.1):
'''''
   从Harrris响应图像中筛选角点
   :param harrisim:
   :param min_dist:
   :param threshold:
   :return:
   '''

   
corner_threshold = harrisim.max() * threshold
harrisim_t = (harrisim > corner_threshold) * 1

   
# 获得候选点的坐标和对应的值  
   
coords = np.array(harrisim_t.nonzero()).T
candidate_values = [harrisim[c[0], c[1]] for c in coords]

# 对候选点排序  
   
index = np.argsort(candidate_values)

# 将可行点存储在数组中  
   
allowed_locations = np.zeros(harrisim.shape)
allowed_locations[min_dist:-min_dist, min_dist:-min_dist] = 1

   
# 按照最小间距原则选择最佳Harris角点  
   
filtered_coords = []
for i in index:
if allowed_locations[coords[i, 0], coords[i, 1]] == 1:
filtered_coords.append(coords[i])
allowed_locations[(coords[i, 0] - min_dist):(coords[i, 0] + min_dist),
           
(coords[i, 1] - min_dist):(coords[i, 1] + min_dist)] = 0

   
return filtered_coords


def plot_corner_points(image, filtered_coords):
'''''
   绘制图像中的角点
   :param image:
   :param filtered_coords:
   :return:
   '''
   
imshow(image)
plot([p[1] for p in filtered_coords], [p[0] for p in filtered_coords], '*')
axis('off')


if __name__ == '__main__':
im = array(Image.open('test.jpg').convert('L'))
harrsim = compute_harris_response(im)
filter_coords1 = get_harris_points(harrsim, 10, 0.1)
filter_coords2 = get_harris_points(harrsim, 10, 0.2)
filter_coords3 = get_harris_points(harrsim, 10, 0.7)
figure()
gray()
fig = plt.figure(figsize=(30, 30))
subplot(131)

plot_corner_points(im, filter_coords1)
title('threshold = 0.1')
subplot(132)
plot_corner_points(im, filter_coords2)
title('threshold = 0.2')
subplot(133)
plot_corner_points(im, filter_coords3)
title('threshold = 0.7')
show()


输出的结果如下图所示:

 

上面我们写出了Harris角点检测程序。对于这个函数,我们需要使用scipy.ndimage.filters模块中的高斯导数滤波器来计算导数。使用高斯滤波器的道理同样是我们需要在角点检测过程中抑制噪声强度。

 

首先我们定义了一个compute_harris_response()函数。在角点相应函数使用高斯导数实现,同样地,参数定义了使用高斯滤波器的尺度大小。你也可以修改这个函数,对x和y方向上不同的尺度参数,以及尝试平均操作中的不同尺度,计算Harris矩阵。

 

这个函数会返回像素值为Harris响应函数值的一幅图像。现在,我们需要从这幅图像中挑选出需要的信息,为此,我们定义了get_harris_points()函数。选取出像素值高于阈值的所有图像点;再加上额外的限制,即角点之间的间隔必须大于设定的最小距离。这种方法会产生很好的角点检测结果。为了实现该算法,我们获取所有的候选像素点,以角点响应值递减的顺序排序,然后将距离已标记为角点位置过近的区域从候选像素点中删除。

 

当我么你有了检测图像中角点所需要的所有函数,为了显示图像中的角点,你可以使用Matplotlib模块绘制函数。


参考文献:

python计算机视觉编程:http://yongyuan.name/pcvwithpython/


更多教程资料请访问:专知AI会员计划

-END-

专 · 知

人工智能领域主题知识资料查看与加入专知人工智能服务群

【专知AI服务计划】专知AI知识技术服务会员群加入人工智能领域26个主题知识资料全集获取

[点击上面图片加入会员]

请PC登录www.zhuanzhi.ai或者点击阅读原文,注册登录专知,获取更多AI知识资料

请加专知小助手微信(扫一扫如下二维码添加),加入专知主题群(请备注主题类型:AI、NLP、CV、 KG等)交流~

关注专知公众号,获取人工智能的专业知识!

点击“阅读原文”,使用专知

登录查看更多
19

相关内容

图像处理(image processing),用计算机对图像进行分析,以达到所需结果的技术。又称影像处理。图像处理一般指数字图像处理。数字图像是指用工业相机、摄像机、扫描仪等设备经过拍摄得到的一个大的二维数组,该数组的元素称为像素,其值称为灰度值。
【干货书】用于概率、统计和机器学习的Python,288页pdf
专知会员服务
280+阅读 · 2020年6月3日
【干货书】机器学习Python实战教程,366页pdf
专知会员服务
330+阅读 · 2020年3月17日
【经典书】Python数据数据分析第二版,541页pdf
专知会员服务
189+阅读 · 2020年3月12日
【经典书】Python计算机视觉编程,中文版,363页pdf
专知会员服务
136+阅读 · 2020年2月16日
【干货】大数据入门指南:Hadoop、Hive、Spark、 Storm等
专知会员服务
94+阅读 · 2019年12月4日
实战 | 用Python做图像处理(三)
七月在线实验室
15+阅读 · 2018年5月29日
实战 | 用Python做图像处理(二)
七月在线实验室
17+阅读 · 2018年5月25日
【干货】​深度学习中的线性代数
专知
21+阅读 · 2018年3月30日
On Feature Normalization and Data Augmentation
Arxiv
14+阅读 · 2020年2月25日
Meta-Learning with Implicit Gradients
Arxiv
13+阅读 · 2019年9月10日
W-net: Bridged U-net for 2D Medical Image Segmentation
Arxiv
19+阅读 · 2018年7月12日
Arxiv
7+阅读 · 2018年3月22日
Arxiv
7+阅读 · 2018年1月21日
VIP会员
相关VIP内容
相关资讯
Top
微信扫码咨询专知VIP会员