Shi-Tomasi 角点检测
·Harris角点检测有一个角点选择准则。
·为每个像素计算一个分数,如果分数高于某个值,则将该像素标记为角点。
·Shi和Tomasi建议取消这项功能。只有特征值可以用来检查像素是否是角点。
·这些角点是对harris角点的一次升级。
%matplotlib inline import numpy as np import cv2 from matplotlib import pyplot as plt img = cv2.imread("imgs/chapter9/shape.jpg", 1) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ################################FOCUS############################### corners = cv2.goodFeaturesToTrack(gray,25,0.01,10) # Self-study: Parameters corners = np.int0(corners) #################################################################### ################################FOCUS############################### for i in corners: x,y = i.ravel() cv2.circle(img,(x,y), 5,(0, 125, 125),-1) ################################################################ plt.figure(figsize=(8, 8)) plt.imshow(img[:,:,::-1]) plt.show()
OpenCV快速角点检测
·选择一个像素,让它的强度为i。
·选择阈值t。
·如上图所示,在像素周围画一个16像素的圆。
·现在,如果圆中存在一组n个连续像素(16个像素),且这些像素都比i+t强度更大,或者都比i-t强度更小,则像素p是一个角点。
1.
import cv2 from matplotlib import pyplot as plt img = cv2.imread('imgs/chapter9/tessellate.png',1) img2 = img.copy() img3 = img.copy() ###############################FOCUS################################ # Initiate FAST object with default values fast = cv2.FastFeatureDetector_create() # find and draw the keypoints kp = fast.detect(img,None) #################################################################### for i in kp: x,y = int(i.pt[0]), int(i.pt[1]) cv2.circle(img2,(x,y), 5,(0, 255, 0),-1) # Print all default params print ("Threshold: ", fast.getThreshold()) print ("nonmaxSuppression: ", fast.getNonmaxSuppression()) print ("neighborhood: ", fast.getType()) print ("Total Keypoints with nonmaxSuppression: ", len(kp)) # Disable nonmaxSuppression fast.setNonmaxSuppression(0) kp = fast.detect(img,None) print ("Total Keypoints without nonmaxSuppression: ", len(kp)) for i in kp: x,y = int(i.pt[0]), int(i.pt[1]) cv2.circle(img3,(x,y), 5,(0, 255, 0),-1) f = plt.figure(figsize=(15,15)) f.add_subplot(2, 1, 1).set_title('Corners with non-maximal-suppression') plt.imshow(img2[:, :,::-1]) f.add_subplot(2, 1, 2).set_title('Corners without non-maximal-suppression') plt.imshow(img3[:, :,::-1]) plt.show()
输出
Threshold: 10 nonmaxSuppression: True neighborhood: 2 Total Keypoints with nonmaxSuppression: 225 Total Keypoints without nonmaxSuppression: 1633
使用OpenCV和PIL进行特征提取和可视化
A级特征
HoG features(方向梯度直方图特征)
- 梯度直方图
- 用于目标检测
步骤
- 查找x和y方向上的梯度
- 使用梯度大小和方向将梯度归类为直方图。
HoG特征对图像中物体的旋转很敏感。
使用Skimage来实现HoG
%matplotlib inlineimport numpy as npimport skimageimport skimage.featureimport cv2from matplotlib import pyplot as pltimg = cv2.imread("imgs/chapter9/plant.jpg", 1)features, output = skimage.feature.hog(img, orientations=9, pixels_per_cell=(8,8),cells_per_block=(3, 3), block_norm='L2-Hys',visualize=True,transform_sqrt=False, feature_vector=True,multichannel=None)print(features.shape)# Rescale histogram for betterdisplayoutput = skimage.exposure.rescale_intensity(output, in_range=(0, 10))f =plt.figure(figsize=(15,15))f.add_subplot(2, 1, 1).set_title('Original Image')plt.imshow(img[:, :,::-1])f.add_subplot(2, 1, 2).set_title('Features')plt.imshow(output)plt.show()
输出
(322218,)
Daisy Features(面向稠密特征提取的可快速计算的局部图像特征描述子)
- 升级版的HOG特征
- 创建一个不适合可视化的稠密特征向量
步骤
- T块->计算梯度或梯度直方图
- S块->使用高斯加权加法(轮廓)组合T块特征
- N块->归一化添加的特征(使范围在0-1之间)
- D块->缩小特征维数(PCA算法)
- Q块->压缩特征用于存储
使用Sklearn实现面向稠密特征提取的可快速计算的局部图像特征描述子
import numpyasnpimport skimageimport skimage.featureimport cv2 from matplotlibimport pyplot as pltimg = cv2.imread("imgs/chapter9/plant.jpg", 0)#img = cv2.resize(img, (img.shape[0]//4,img.shape[1]//4))features, output = skimage.feature.daisy(img, step=180, radius=58, rings=2, histograms=8, orientations=9, visualize=True)print(features.shape)f = plt.figure(figsize=(15,15))f.add_subplot(2, 1, 1).set_title('Original Image');plt.imshow(img, cmap="gray")f.add_subplot(2, 1, 2).set_title('Features');plt.imshow(output);plt.show()
输出
(2, 3, 153)
GLCM Features(灰度共生矩阵特征)
- 灰度协方差矩阵
- 计算各像素在不同方面(同质性、均匀性)的整体平均相关程度。
- 灰度共生矩阵(GLCM)通过计算灰度像素i与j在特定空间关系中出现的频率。
使用Skimage实现GLCM
'''
Source: https://scikitimage.org/docs/dev/auto_examples/features_detection/plot_glcm.html'''importmatplotlib.pyplotasplt
from skimage.featureimport greycomatrix, greycoprops from skimageimport data PATCH_SIZE = 21 # open the camera image image = data.camera() # select some patches from grassy areas of the image grass_locations = [(474, 291), (440, 433), (466, 18), (462, 236)] grass_patches = [] for loc in grass_locations: grass_patches.append(image[loc[0]:loc[0] + PATCH_SIZE, loc[1]:loc[1] + PATCH_SIZE]) # select some patches from sky areas of the image sky_locations = [(54, 48), (21, 233), (90, 380), (195, 330)] sky_patches = [] for loc in sky_locations: sky_patches.append(image[loc[0]:loc[0] + PATCH_SIZE, loc[1]:loc[1] + PATCH_SIZE]) # compute some GLCM properties each patch xs = [] ys = [] for patch in (grass_patches + sky_patches): glcm = greycomatrix(patch, [5], [0], 256, symmetric=True, normed=True) xs.append(greycoprops(glcm, 'dissimilarity')[0, 0]) ys.append(greycoprops(glcm, 'correlation')[0, 0]) # create the figure fig = plt.figure(figsize=(8, 8)) # display original image with locations of patches ax = fig.add_subplot(3, 2, 1) ax.imshow(image, cmap=plt.cm.gray, interpolation='nearest', vmin=0, vmax=255) for (y, x) in grass_locations: ax.plot(x + PATCH_SIZE / 2, y + PATCH_SIZE / 2, 'gs') for (y, x) in sky_locations: ax.plot(x + PATCH_SIZE / 2, y + PATCH_SIZE / 2, 'bs') ax.set_xlabel('Original Image') ax.set_xticks([]) ax.set_yticks([]) ax.axis('image') # for each patch, plot (dissimilarity, correlation) ax = fig.add_subplot(3, 2, 2) ax.plot(xs[:len(grass_patches)], ys[:len(grass_patches)], 'go', label='Grass') ax.plot(xs[len(grass_patches):], ys[len(grass_patches):], 'bo', label='Sky') ax.set_xlabel('GLCM Dissimilarity') ax.set_ylabel('GLCM Correlation') ax.legend() # display the image patchesfor i, patch in enumerate(grass_patches): ax = fig.add_subplot(3, len(grass_patches), len(grass_patches)*1 + i + 1) ax.imshow(patch, cmap=plt.cm.gray, interpolation='nearest', vmin=0, vmax=255) ax.set_xlabel('Grass %d' % (i + 1)) for i, patch in enumerate(sky_patches): ax = fig.add_subplot(3, len(sky_patches), len(sky_patches)*2 + i + 1) ax.imshow(patch, cmap=plt.cm.gray, interpolation='nearest', vmin=0, vmax=255) ax.set_xlabel('Sky %d' % (i + 1)) # display the patches and plotfig.suptitle('Grey level co-occurrence matrix features', fontsize=14) plt.show()
HAAR Features(哈尔特征)
- 用于物体识别
哈尔矩形特征
- 矩形内区域像素之和的差值。
- 每个特征都是一个单独的值,由白色矩形下的像素之和减去黑色矩形下的像素之和得到。
'''
Source:
https://scikitimage.org/docs/dev/auto_examples/features_detection/plot_haar.html
''' # Haar like feature Descriptors
importnumpyasnp importmatplotlib.pyplotasplt importskimage.feature fromskimage.featureimport haar_like_feature_coord, draw_haar_like_feature images = [np.zeros((2, 2)), np.zeros((2, 2)),np.zeros((3, 3)), np.zeros((3, 3)),np.zeros((2, 2))] feature_types = ['type-2-x', 'type-2-y','type-3-x', 'type-3-y', 'type-4'] fig, axs = plt.subplots(3, 2) for ax, img, feat_t in zip(np.ravel(axs), images, feature_types): coord, _ = haar_like_feature_coord(img.shape[0], img.shape[1], feat_t) haar_feature = draw_haar_like_feature(img, 0, 0, img.shape[0],img.shape[1],coord,max_n_features=1, random_state=0) ax.imshow(haar_feature) ax.set_title(feat_t) ax.set_xticks([]) ax.set_yticks([]) fig.suptitle('The different Haar-like feature descriptors') plt.axis('off') plt.show()
LBP Features(局部二值模式特征)
- 局部二值模式
要素
- LBP阈值
- 特征求和
import numpyas npimport skimageimport skimage.featureimport cv2from matplotlib import pyplot as pltimg = cv2.imread("imgs/chapter9/plant.jpg", 0);#img = cv2.resize(img,(img.shape[0]//4,img.shape[1]//4)); output = skimage.feature.local_binary_pattern(img, 3, 8, method='default')print(features.shape); # Rescale histogram for betterdisplay#output = skimage.exposure.rescale_intensity(output,in_range=(0, 10)) f = plt.figure(figsize=(15,15))f.add_subplot(2, 1, 1).set_title('Original Image');plt.imshow(img, cmap="gray")f.add_subplot(2, 1, 2).set_title('Features');plt.imshow(output);plt.show()
输出
(2,3, 153)
Blobs as features(斑点作为特征)
- Blob检测方法的目的是检测数字图像中与周围区域相比具有不同属性(如亮度或颜色)的区域。
- 通俗地说,blob是图像的一个区域,其中一些属性是常量或近似常量,可以认为blob中的所有点在某种意义上是相似的。
使用Skimage来实现Blobs
import numpyas npimport skimageimport skimage.featureimport cv2import mathfrom matplotlib import pyplot as plt img = cv2.imread("imgs/chapter9/shape.jpg", 0)#img =skimage.data.hubble_deep_field()[0:500, 0:500]#image_gray =skimage.color.rgb2gray(image) blobs = skimage.feature.blob_dog(img, max_sigma=5, threshold=0.05) blobs[:, 2] = blobs[:, 2]print(blobs.shape) for y , x, r in blobs:cv2.circle(img,(int(x), int(y)), int(r), (0,255,0), 1) f = plt.figure(figsize=(15,15))f.add_subplot(2, 1, 1).set_title('Original Image');plt.imshow(img, cmap="gray")plt.show()
输出
(91, 3)
使用Blobs检测外太空星系
'''
Source:
https://scikitimage.org/docs/dev/auto_examples/features_detection/plot_blob.html
'''
from mathimport sqrtfromskimage import datafromskimage.feature import blob_dog, blob_log, blob_dohfromskimage.color import rgb2gray importmatplotlib.pyplot as plt image =data.hubble_deep_field()[0:500, 0:500]image_gray= rgb2gray(image) blobs_log= blob_log(image_gray, max_sigma=30, num_sigma=10, threshold=.1) # Computeradii in the 3rd column.blobs_log[:,2] = blobs_log[:, 2] * sqrt(2) blobs_dog= blob_dog(image_gray, max_sigma=30, threshold=.1)blobs_dog[:,2] = blobs_dog[:, 2] * sqrt(2) blobs_doh= blob_doh(image_gray, max_sigma=30, threshold=.01) blobs_list= [blobs_log, blobs_dog, blobs_doh]colors =['yellow', 'lime', 'red']titles =['Laplacian of Gaussian', 'Difference of Gaussian', 'Determinant of Hessian']sequence= zip(blobs_list, colors, titles) fig, axes= plt.subplots(3, 1, figsize=(15, 15), sharex=True, sharey=True)ax =axes.ravel()for idx,(blobs, color, title) in enumerate(sequence): ax[idx].set_title(title) ax[idx].imshow(image,interpolation='nearest') for blob in blobs: y, x, r = blob c = plt.Circle((x, y), r, color=color,linewidth=2, fill=False) ax[idx].add_patch(c) ax[idx].set_axis_off() plt.tight_layout()plt.show()
B级特征
SIFT Features(尺度不变特征变换特征)
- 尺度不变特征变换
- 专利持有人是加拿大的UBC大学
SIFT具有特征如下 :
- 尺度不变性(图像尺度变化,提取的特征不变)
- 旋转不变性(图像旋转,提取的特征不变)
- 亮度不变性(亮度发生改变,提取的特征不变)
- 视角不变性(视角变化,提取的特征不变)
SIFT提取步骤
- 构建规模空间金字塔
- 使用近似LOG算子处理特征和梯度
- 在高斯图像的差分中找出最大和最小的关键点。
- 剔除非关键点
- 给关键点分配一个方向。
- 生成最终的SIFT特征—为缩放和旋转不变性生成一个新的表示。
使用OpenCV实现SIFT
'''
NOTE: Patented work. Cannot be used for commercial purposes1.pip installopencv-contrib-python==3.4.2.162.pip install opencv-python==3.4.2.16
'''
import numpy as npimport cv2print(cv2.__version__)from matplotlib import pyplot as pltimg = cv2.imread("imgs/chapter9/indoor.jpg", 1); gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) sift = cv2.xfeatures2d.SIFT_create()keypoints, descriptors = sift.detectAndCompute(gray, None) for i in keypoints: x,y = int(i.pt[0]), int(i.pt[1]) cv2.circle(img,(x,y), 5,(0, 125,125),-1) plt.figure(figsize=(8, 8))plt.imshow(img[:,:,::-1]);plt.show()
CenSurE Features(中心环绕特征)
- 中心环绕用于实时特征检测
- 胜过许多其他关键点检测器和特征提取器。
CenSureE具有特征如下 :
- 尺度不变性(图像尺度变化,提取的特征不变)
- 旋转不变性(图像旋转,提取的特征不变)
- 亮度不变性(亮度发生改变,提取的特征不变)
- 视角不变性(视角变化,提取的特征不变)
使用Skimage实现CENSURE
import numpyas npimport cv2import skimage.featurefrom matplotlib import pyplot as pltimg = cv2.imread("imgs/chapter9/indoor.jpg", 1); gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) detector = skimage.feature.CENSURE(min_scale=1, max_scale=7, mode='Star',non_max_threshold=0.05, line_threshold=10) detector.detect(gray) for i in detector.keypoints:x,y = int(i[1]), int(i[0])cv2.circle(img,(x,y), 5,(0, 125, 125),-1) plt.figure(figsize=(8, 8))plt.imshow(img[:,:,::-1]);plt.show()
SURFFeatures(快速鲁棒特征)
- 快速鲁棒特征
- 已获得专利的局部特征检测器和特征描述子
- 标准版本的SURF比SIFT要快好几倍
SURF使用的算法:
- Hessian斑点检测器行列式的整数近似值
- Haar小波响应之和
- 多分辨率金字塔
SUFR特性有:
- 尺度不变性(图像尺度变化,提取的特征不变)
- 旋转不变性(图像旋转,提取的特征不变)
- 视角不变性(视角变化,提取的特征不变)
'''
NOTE: Patented work. Cannot be used for commercial purposes
1.pip install opencv-contrib-python==3.4.2.16
2.pip install opencv-python==3.4.2.16
import numpy as np importcv2 frommatplotlibimport pyplot as plt img = cv2.imread("imgs/chapter9/indoor.jpg", 1); gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) surf = cv2.xfeatures2d.SURF_create(1000) keypoints, descriptors = surf.detectAndCompute(gray, None) for i in keypoints: x,y = int(i.pt[0]), int(i.pt[1]) cv2.circle(img,(x,y), 5,(0, 125, 125),-1) plt.figure(figsize=(8, 8)) plt.imshow(img[:,:,::-1]); plt.show()