特征提取:几何特征

一、特征提取:几何特征

图像几何特征提取有两种提取方法,一种是基于边缘的提取,另一种是基于特征点的特征描述算子。
基于边缘的提取像素值函数快速变化的区域,一阶导数的极值区域
特点像素明显变化,语义丰富;
提取:先高斯去噪,再使用一阶导数获取极值(梯度下降),原因在于导数对噪声敏感
不同标准差的波(x方向)能捕捉到不同尺度的边缘
用途:物体识別,几何、视角变换

基于特征点的特征描述算子:
特点:图像不管咋变化,特征点可以稳定局部,具有可重复性、显著性
用途:图像配准/拼接;运动跟踪;物体识别;机器人导航;3D重建

兴趣点/关键点:
Haris角点:一种显著点,在任何方向上移动小窗口,导致大的像素变动
Fast角点:理解:考虑灰度图像,即若该点的灰度值比其周围领域内足够多的像素点的灰度值大或者小,则该点可能为角点
优点:计算复杂度小,检测效果好
缺点:不产生多尺度特征,也没有方向信息,这样会失去旋转不变性
使用:ORB,结合Fast角点的特征点检测与 BRIEF特征描述技术,速度比SIFT和SURF都快

Blob斑点
理解:拉普拉斯梯度,二阶导取极值的地方,对噪声敏感
步骤:高斯卷积核滤波降噪,再使用拉普拉斯算子进行边缘检测
使用1:
SIFT基于尺度空间不变的特征:
特点:
不变性:旋转、缩放等
独特性好,信息丰富,可以在海量数据库中精确匹配
多量:即使少数物体也能产生大量SIFT特征
计算快
处理:
Log空间转为Dog空间,既高斯到拉普拉斯改成差分高斯
对关键点处理,用位置插值找到关键点的精确位置,再去除边缘上不稳定的点
关键点方向估计:8个方向,获取最高值为主方向,将超多最高值80%的方向称为辅方向
关键点描述子生成,区域坐标旋转,计算采样区域的直方图
使用2:
SURF:
把SIFT的高斯二阶微分的模板进行了简化,使得卷积平滑操作仅需要转换成加减运算
在方向确定阶段,在圆形区域计算x,y方向的haar小波响应,找到最大的扇形方向,为了找特征点,需要变换原图,变换图就是原图每个像素的 Hessian矩阵行列式的近似值构成的
求 Hessian要先高斯平滑,再求二阶导数,对于离散像素,两个操作合在一起用Haar小波替换即可
特点:亮度变化下效果好,模糊方面优于 SIFT,尺度不变上不及SIFT,旋转不变上差很多

二、基于边缘的特征提取

以下图为例
在这里插入图片描述
其灰度图像及其强度直方图:
在这里插入图片描述

使用Canny边缘检测器获取特征的边缘
在这里插入图片描述填充这些轮廓
在这里插入图片描述

删除小目标
在这里插入图片描述从图像的背景中分离出前景
在这里插入图片描述
计算标记
在这里插入图片描述
从确定的标记点开始注入高程图的区域
在这里插入图片描述

在这里插入图片描述基于边界的区域分类
在这里插入图片描述
代码:

import numpy as np
import cv2
from skimage.transform import (hough_line, hough_line_peaks, hough_circle,
hough_circle_peaks)
from skimage.draw import circle_perimeter
from skimage.feature import canny
from skimage.data import astronaut
from skimage.io import imread, imsave
from skimage.color import rgb2gray, gray2rgb, label2rgb
from skimage import img_as_float
from skimage.morphology import skeletonize
from skimage import data, img_as_float
import matplotlib.pyplot as pylab
from matplotlib import cm
from skimage.filters import sobel, threshold_otsu
from skimage.feature import canny
from skimage.segmentation import felzenszwalb, slic, quickshift, watershed
from skimage.segmentation import mark_boundaries, find_boundaries

coins = cv2.imread("11.jpg")
hist = np.histogram(coins, bins=np.arange(0, 256), normed=True)
fig, axes = pylab.subplots(1, 2, figsize=(20, 10))
axes[0].imshow(coins, cmap=pylab.cm.gray, interpolation='nearest')
axes[0].axis('off'), axes[1].plot(hist[1][:-1], hist[0], lw=2)
axes[1].set_title('histogram of gray values')
pylab.show()

img = cv2.imread('11.jpg')
Grayimg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(Grayimg, 12, 255,cv2.THRESH_BINARY)
coins=thresh

edges = canny(coins, sigma=2)
fig, axes = pylab.subplots(figsize=(10, 6))
axes.imshow(edges, cmap=pylab.cm.gray, interpolation='nearest')
axes.set_title('Canny detector'), axes.axis('off'), pylab.show()

from scipy import ndimage as ndi
fill_coins = ndi.binary_fill_holes(edges)
fig, axes = pylab.subplots(figsize=(10, 6))
axes.imshow(fill_coins, cmap=pylab.cm.gray, interpolation='nearest')
axes.set_title('filling the holes'), axes.axis('off'), pylab.show()

from skimage import morphology
coins_cleaned = morphology.remove_small_objects(fill_coins, 21)
fig, axes = pylab.subplots(figsize=(10, 6))
axes.imshow(coins_cleaned, cmap=pylab.cm.gray, interpolation='nearest')
axes.set_title('removing small objects'), axes.axis('off'), pylab.show()

elevation_map = sobel(coins)
fig, axes = pylab.subplots(figsize=(10, 6))
axes.imshow(elevation_map, cmap=pylab.cm.gray, interpolation='nearest')
axes.set_title('elevation map'), axes.axis('off'), pylab.show()
markers = np.zeros_like(coins)
markers[coins < 30] = 1
markers[coins > 150] = 2
print(np.max(markers), np.min(markers))
fig, axes = pylab.subplots(figsize=(10, 6))
a = axes.imshow(markers, cmap=plt.cm.hot, interpolation='nearest')
plt.colorbar(a)
axes.set_title('markers'), axes.axis('off'), pylab.show()

markers = np.zeros_like(coins)
markers[coins < 30] = 1
markers[coins > 150] = 2
print(np.max(markers), np.min(markers))
fig, axes = pylab.subplots(figsize=(10, 6))
a = axes.imshow(markers, cmap=plt.cm.hot, interpolation='nearest')
plt.colorbar(a)
axes.set_title('markers'), axes.axis('off'), pylab.show()

segmentation = morphology.watershed(elevation_map, markers)
fig, axes = pylab.subplots(figsize=(10, 6))
axes.imshow(segmentation, cmap=pylab.cm.gray, interpolation='nearest')
axes.set_title('segmentation'), axes.axis('off'), pylab.show()

segmentation = ndi.binary_fill_holes(segmentation - 1)
labeled_coins, _ = ndi.label(segmentation)
image_label_overlay = label2rgb(labeled_coins, image=coins)
fig, axes = pylab.subplots(1, 2, figsize=(20, 6), sharey=True)
axes[0].imshow(coins, cmap=pylab.cm.gray, interpolation='nearest')
axes[0].contour(segmentation, [0.5], linewidths=1.2, colors='y')
axes[1].imshow(image_label_overlay, interpolation='nearest')
for a in axes:
 a.axis('off')
pylab.tight_layout(), pylab.show()

三、SIFT基于尺度空间不变的特征

以下面两张图为例:
在这里插入图片描述在这里插入图片描述
SIFT特征提取并对应后:
在这里插入图片描述

如果仅以第一张图片为例,其旋转后的图片作为另一张图片,如下图所示:
在这里插入图片描述
则特征匹配后的图像
在这里插入图片描述
代码:

original = rgb2gray(imread('toy.jpg'));
figure;
imshow(original);

scale = 1.3;
J = imresize(original,scale);
theta = 31;
distorted = imrotate(J,theta);
figure
imshow(distorted)

ptsOriginal  = detectSURFFeatures(original);
ptsDistorted = detectSURFFeatures(distorted);

[featuresOriginal,validPtsOriginal] = ...
            extractFeatures(original,ptsOriginal);
[featuresDistorted,validPtsDistorted] = ...
            extractFeatures(distorted,ptsDistorted);
        
indexPairs = matchFeatures(featuresOriginal,featuresDistorted);

matchedOriginal  = validPtsOriginal(indexPairs(:,1));
matchedDistorted = validPtsDistorted(indexPairs(:,2));

figure
showMatchedFeatures(original,distorted,matchedOriginal,matchedDistorted)
title('Candidate matched points (including outliers)')

四、SURF

在这里插入图片描述
代码

original = rgb2gray(imread('toy.jpg'));
figure;
imshow(original);
text(size(original,2),size(original,1)+15, ...
    'Image courtesy of Massachusetts Institute of Technology', ...
    'FontSize',7,'HorizontalAlignment','right');

scale = 1.3;
J = imresize(original, scale);
 
theta = 31;
distorted = imrotate(J,theta);
figure
imshow(distorted)

ptsOriginalBRISK  = detectBRISKFeatures(original,'MinContrast',0.01);
ptsDistortedBRISK = detectBRISKFeatures(distorted,'MinContrast',0.01);

ptsOriginalSURF  = detectSURFFeatures(original);
ptsDistortedSURF = detectSURFFeatures(distorted);

[featuresOriginalFREAK,validPtsOriginalBRISK]  = ...
        extractFeatures(original,ptsOriginalBRISK);
[featuresDistortedFREAK,validPtsDistortedBRISK] = ...
        extractFeatures(distorted,ptsDistortedBRISK);

[featuresOriginalSURF,validPtsOriginalSURF]  = ...
        extractFeatures(original,ptsOriginalSURF);
[featuresDistortedSURF,validPtsDistortedSURF] = ...
        extractFeatures(distorted,ptsDistortedSURF);
    
indexPairsBRISK = matchFeatures(featuresOriginalFREAK,...
            featuresDistortedFREAK,'MatchThreshold',40,'MaxRatio',0.8);

indexPairsSURF = matchFeatures(featuresOriginalSURF,featuresDistortedSURF);

matchedOriginalBRISK  = validPtsOriginalBRISK(indexPairsBRISK(:,1));
matchedDistortedBRISK = validPtsDistortedBRISK(indexPairsBRISK(:,2));

matchedOriginalSURF  = validPtsOriginalSURF(indexPairsSURF(:,1));
matchedDistortedSURF = validPtsDistortedSURF(indexPairsSURF(:,2));

figure
showMatchedFeatures(original,distorted,matchedOriginalBRISK,...
            matchedDistortedBRISK)
title('Putative matches using BRISK & FREAK')
legend('ptsOriginalBRISK','ptsDistortedBRISK')

  • 4
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值