1 傳統演算法目標檢測
區域選擇 --> 特征提取 --> 特征分類
1.1 區域選擇 python 實作 影像滑動視窗
區域選取:首先選取影像中可能出現物體的位置,由于物體位置、大小都不固定,因此傳統演算法通常使用滑動視窗(Sliding Windows)演算法,但這種演算法會存在大量的冗余框,并且計算復雜度高,
滑動視窗: 固定一個視窗,截取圖片
1.1.1 以滑動視窗方式切分影像
import cv2
def sliding_window(src_img,step,windowsize):
'''
src_img : 源影像
out_img : 輸出影像
step : 步進步長 元組型別
windowsize :視窗大小 元組型別
'''
cnt = 0 # 記錄滑動視窗數目
for y in range(0,src_img.shape[0],step[1]):
for x in range(0,src_img.shape[1],step[0]):
image_patch = src_img[y:y+windowsize[0],x:x+windowsize[1]]
cnt += 1
cv2.imwrite("image/sliding_img/"+str(cnt)+".png",image_patch)
if __name__ == "__main__":
img = cv2.imread("image/src_img/1.jpg")
step = (50,50)
windowsize = (100,100)
sliding_window(img,step,windowsize)
1.1.2 滑動視窗簡單影片演示
import cv2
import numpy as np
import matplotlib.pyplot as plt
def sliding_window(path,step,windowsize):
'''
src_img : 源影像
out_img : 輸出影像
step : 步進步長 元組型別
windowsize :視窗大小 元組型別
'''
# cv2.fillConvexPoly()函式可以用來填充凸多邊形,只需要提供凸多邊形的頂點即可.
src_img = cv2.imread(path)
for y in range(0,src_img.shape[0],step[1]):
for x in range(0,src_img.shape[1],step[0]):
# 先計算坐標
x_min = x
y_min = y
x_max = x + windowsize[1]
y_max = y + windowsize[0]
src_img1 = cv2.imread(path)
src_img2 = cv2.cvtColor(src_img1,cv2.COLOR_BGR2RGB)
rectangle = np.array([[x_min,y_min],[x_min,y_max],[x_max,y_max],[x_max,y_min]])
# cv2.fillConvexPoly 單個多邊形填充
cv2.fillConvexPoly(src_img2,rectangle,(0,0,0)) # (0,0,0) 顏色填充
plt.imshow(src_img2)
plt.show()
plt.pause(0.1)
plt.clf()
if __name__ == "__main__":
plt.ion() # 使得plt.show()顯示后不暫停,互動模式,可以使用plt.ioff()停止
path = "image/src_img/1.jpg"
step = (50,50)
windowsize = (200,200)
sliding_window(path,step,windowsize)

1.2 特征提取
特征提取:在得到物體位置后,通常使用人工精心設計的提取器進行特征提取,如SIFT和HOG等,由于提取器包含的引數較少,并且人工設計的魯棒性較低,因此特征提取的質量并不高,
1.2.1 python提取影像SIFT特征
SIFT(Scale-invariant feature transform),也叫尺度不變特征變換演算法,是David Lowe于1999年提出的區域特征描述子(Descriptor),并于2004年進行了更深入的發展和完善,Sift特征匹配演算法可以處理兩幅影像之間發生平移、旋轉、仿射變換情況下的匹配問題,具有很強的匹配能力,Mikolajczyk對包括Sift算子在內的十種區域描述子所做的不變性對比實驗中,Sift及其擴展演算法已被證實在同類描述子中具有最強的健壯性,
其應用范圍包含物體辨識、機器人地圖感知與導航、影像縫合、3D模型建立、手勢辨識、影像追蹤和動作比對,區域影像特征的描述與偵測可以幫助辨識物體,SIFT 特征是基于物體上的一些區域外觀的興趣點而與影像的大小和旋轉無關,對于光線、噪聲、些微視角改變的容忍度也相當高,基于這些特性,它們是高度顯著而且相對容易擷取,在母數龐大的特征資料庫中,很容易辨識物體而且鮮有誤認,
python-opencv提取SIFT特征為以下步驟:
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image/src_img/1.jpg')
cv2.imshow("original",img)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
sift = cv2.xfeatures2d.SIFT_create() # 創建sift物件
keypoints, descriptor = sift.detectAndCompute(gray, None) # 檢測單通道影像特征點
# 繪制特征點
cv2.drawKeypoints(image = img,
outImage = img,
keypoints = keypoints,
flags = cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,
color = (51,163,236))
cv2.imshow("SIFT",img)
cv2.waitKey(0)
cv2.destroyAllWindows()

為了體現SIFT特征的作用,我將圖片加入旋轉,看是否能實作影像匹配,
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image/src_img/1.jpg')
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
# 為了能夠在任意位置進行旋轉變換,OpenCV提供了一個函式:cv2.getRotationMarix2D( ),這個函式需要三個引數,旋轉中心,旋轉角度,旋轉后影像的縮放比例:
rows, cols = img.shape[:2]
M1 = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 0.5)
# cv2.warpAffine(img, rot_mat, (img.shape[1], img.shape[0]))
# 引數說明: img表示輸入的圖片,rot_mat表示仿射變化矩陣,(image.shape[1], image.shape[0])表示變換后的圖片大小
img1 = cv2.warpAffine(img, M1, (cols, rows))
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
gray1 = cv2.cvtColor(img1, cv2.COLOR_RGB2GRAY)
sift = cv2.ORB_create() # 創建sift物件
keypoints, descriptor = sift.detectAndCompute(gray, None) # 檢測單通道影像特征點和描述符
keypoints1, descriptor1 = sift.detectAndCompute(gray1, None) # 檢測單通道影像特征點和描述符
# 創建BFMatcher物件
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
mathces = bf.match(descriptor,descriptor1) #匹配描述子
mathces=sorted(mathces,key=lambda x:x.distance) #據距離來排序
# 繪制特征點
img2 = cv2.drawMatches(img1=img,
keypoints1=keypoints,
img2=img1,
keypoints2=keypoints1,
matches1to2=mathces[:10],
outImg = None
) #畫出匹配關系
plt.imshow(img2)
plt.show()

從結果可以看出,SIFT特征能有效應對幾何變換,能夠很好實作影像匹配,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/335334.html
標籤:其他
