最近學(xué)習(xí)了opencv的相關(guān)操作退腥,更新一下對(duì)樂(lè)譜的識(shí)別技術(shù)。首先介紹關(guān)鍵操作:ORB特征在python下的使用:
ORB算法的參數(shù)是使用ORB_create()函數(shù)設(shè)置的纱意。 ORB_create()函數(shù)的參數(shù)及其默認(rèn)值如下所示:
cv2.ORB_create(nfeatures = 500,
scaleFactor = 1.2,
nlevels = 8,
edgeThreshold = 31,
firstLevel = 0,
WTA_K = 2,
scoreType = HARRIS_SCORE,
patchSize = 31,
fastThreshold = 20)
參數(shù)解釋?zhuān)?/h3>
nfeatures - int
確定要查找的功能(關(guān)鍵點(diǎn))的最大數(shù)量洽洁。
scaleFactor - float
金字塔抽取比率必須大于1.ORB使用圖像金字塔來(lái)查找要素,因此您必須提供金字塔中每層之間的比例因子和金字塔所具有的層數(shù)订晌。 scaleFactor = 2表示古典金字塔虏辫,每個(gè)下一個(gè)級(jí)別的像素比前一個(gè)像素少4倍。大比例因子將減少找到的功能數(shù)量锈拨。
nlevels - int
金字塔等級(jí)的數(shù)量砌庄。最小級(jí)別的線性大小等于input_image_linear_size / pow(scaleFactor,nlevels)奕枢。
edgeThreshold - - int
未檢測(cè)到要素的邊框的大小娄昆。由于關(guān)鍵點(diǎn)具有特定的像素大小,因此圖像的邊緣必須從搜索中排除缝彬。 edgeThreshold的大小應(yīng)該等于或大于patchSize參數(shù)萌焰。
firstLevel - int
此參數(shù)允許您確定哪個(gè)級(jí)別應(yīng)視為金字塔中的第一級(jí)。在當(dāng)前的實(shí)現(xiàn)中它應(yīng)該是0谷浅。通常扒俯,具有統(tǒng)一比例的金字塔等級(jí)被認(rèn)為是第一等級(jí)。
WTA_K - int
用于產(chǎn)生定向的BRIEF描述符的每個(gè)元素的隨機(jī)像素的數(shù)量一疯『承可能的值是2,3和4,其中2是默認(rèn)值墩邀。例如掌猛,3的值意味著一次選擇三個(gè)隨機(jī)像素來(lái)比較它們的亮度。最亮像素的索引被返回眉睹。由于有3個(gè)像素荔茬,返回的索引將為0,1或2只盹。
scoreType - int
該參數(shù)可以設(shè)置為HARRIS_SCORE或FAST_SCORE。默認(rèn)的HARRIS_SCORE表示Harris corner算法用于對(duì)要素進(jìn)行排名兔院。該分?jǐn)?shù)僅用于保留最佳功能殖卑。 FAST_SCORE產(chǎn)生的穩(wěn)定關(guān)鍵點(diǎn)稍低,但計(jì)算速度稍快坊萝。
patchSize - int
面向BRIEF描述符使用的補(bǔ)丁大小孵稽。當(dāng)然,在較小的金字塔層上十偶,由特征覆蓋的感知圖像區(qū)域?qū)⒏蟆?/p>
# Import copy to make copies of the training image
import copy
# Set the default figure size
plt.rcParams['figure.figsize'] = [14.0, 7.0]
# Set the parameters of the ORB algorithm by specifying the maximum number of keypoints to locate and
# the pyramid decimation ratio
orb = cv2.ORB_create(200, 2.0)
# Find the keypoints in the gray scale training image and compute their ORB descriptor.
# The None parameter is needed to indicate that we are not using a mask.
keypoints, descriptor = orb.detectAndCompute(training_gray, None)
# Create copies of the training image to draw our keypoints on
keyp_without_size = copy.copy(training_image)
keyp_with_size = copy.copy(training_image)
# Draw the keypoints without size or orientation on one copy of the training image
cv2.drawKeypoints(training_image, keypoints, keyp_without_size, color = (0, 255, 0))
"""
下面的方法就是把關(guān)鍵點(diǎn)以及范圍描述出來(lái)
"""
# Draw the keypoints with size and orientation on the other copy of the training image
cv2.drawKeypoints(training_image, keypoints, keyp_with_size, flags = cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# Display the image with the keypoints without size or orientation
plt.subplot(121)
plt.title('Keypoints Without Size or Orientation')
plt.imshow(keyp_without_size)
# Display the image with the keypoints with size and orientation
plt.subplot(122)
plt.title('Keypoints With Size and Orientation')
plt.imshow(keyp_with_size)
plt.show()
# Print the number of keypoints detected
print("\nNumber of keypoints Detected: ", len(keypoints))
特征比對(duì)
cv2.BFMatcher(normType = cv2.NORM_L2,
crossCheck = false)
normType
指定用于確定匹配質(zhì)量的度量菩鲜。默認(rèn)情況下,normType = cv2.NORM_L2惦积,它測(cè)量?jī)蓚€(gè)描述符之間的距離接校。但是,對(duì)于由ORB創(chuàng)建的二進(jìn)制描述符狮崩,海明度量標(biāo)準(zhǔn)更適合蛛勉。漢明度量通過(guò)計(jì)算二進(jìn)制描述符之間的不相似位的數(shù)量來(lái)確定距離。當(dāng)使用WTA_K = 2創(chuàng)建ORB描述符時(shí)睦柴,選擇兩個(gè)隨機(jī)像素并在亮度上進(jìn)行比較诽凌。最亮像素的索引返回為0或1.這種輸出只占用1位,因此應(yīng)該使用cv2.NORM_HAMMING度量坦敌。另一方面侣诵,如果使用WTA_K = 3創(chuàng)建ORB描述符,則選擇三個(gè)隨機(jī)像素并在亮度上進(jìn)行比較狱窘。最亮像素的索引返回為0,1或2.這樣的輸出將占用2位杜顺,因此稱(chēng)為cv2.NORM_HAMMING2(2代表2位)的漢明距離的特殊變體應(yīng)該是代替使用。然后蘸炸,對(duì)于選擇的任何度量躬络,當(dāng)比較訓(xùn)練和查詢圖像中的關(guān)鍵點(diǎn)時(shí),具有較小度量(它們之間的距離)的對(duì)被認(rèn)為是最佳匹配幻馁。
crossCheck - bool
一個(gè)布爾變量洗鸵,可以設(shè)置為T(mén)rue或False越锈。交叉檢查對(duì)于消除錯(cuò)誤匹配非常有用仗嗦。通過(guò)兩次執(zhí)行匹配程序進(jìn)行交叉檢查。第一次將訓(xùn)練圖像中的關(guān)鍵點(diǎn)與查詢圖像中的關(guān)鍵點(diǎn)進(jìn)行比較;然而甘凭,第二次將查詢圖像中的關(guān)鍵點(diǎn)與訓(xùn)練圖像中的關(guān)鍵點(diǎn)進(jìn)行比較(即稀拐,比較是向后完成的)。當(dāng)啟用交叉檢查時(shí)丹弱,只有在訓(xùn)練圖像中的關(guān)鍵點(diǎn)A是查詢圖像中關(guān)鍵點(diǎn)B的最佳匹配(反之亦然)(即德撬,如果查詢圖像中的關(guān)鍵點(diǎn)B是訓(xùn)練圖像中的點(diǎn)A)铲咨。
# Set the default figure size
plt.rcParams['figure.figsize'] = [34.0, 34.0]
# Create a Brute Force Matcher object. We set crossCheck to True so that the BFMatcher will only return consistent
# pairs. Such technique usually produces best results with minimal number of outliers when there are enough matches.
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck = True)
# Perform the matching between the ORB descriptors of the training image and the query image
matches = bf.match(descriptors_train, descriptors_query)
# The matches with shorter distance are the ones we want. So, we sort the matches according to distance
matches = sorted(matches, key = lambda x : x.distance)
# Connect the keypoints in the training image with their best matching keypoints in the query image.
# The best matches correspond to the first elements in the sorted matches list, since they are the ones
# with the shorter distance. We draw the first 85 mathces and use flags = 2 to plot the matching keypoints
# without size or orientation.
result = cv2.drawMatches(training_gray, keypoints_train, query_gray, keypoints_query, matches[:85], query_gray, flags = 2)
# we display the image
plt.title('Best Matching Points', fontsize = 30)
plt.imshow(result)
plt.show()
# Print the number of keypoints detected in the training image
print("Number of Keypoints Detected In The Training Image: ", len(keypoints_train))
# Print the number of keypoints detected in the query image
print("Number of Keypoints Detected In The Query Image: ", len(keypoints_query))
# Print total number of matching Keypoints between the training and query images
print("\nNumber of Matching Keypoints Between The Training and Query Images: ", len(matches))
樂(lè)譜中的應(yīng)用
import cv2
import numpy as np
import matplotlib.pyplot as plt
import os
import copy
"""
使用順序:
upload_pic(path) 傳入文件夾路徑
select_pic(i) 選定第i個(gè)圖
show_pic() 查看此圖像
show_area(x,xx,y,yy) 展示圖片區(qū)域
set_aim_area() 將展示的區(qū)域設(shè)為目標(biāo)圖像
show_feature() 以默認(rèn)參數(shù)運(yùn)行ORB set_cv_parements()修改參數(shù)
serch_featrue() 在當(dāng)前圖片中搜索匹配
plot_result() 將搜索到的部分展示出來(lái)(最大30 張)
"""
class Score(object):
def upload_pic(self,path):
piclistdr=self.walkFile_item(path)
self.picture_list=self.read_picture(piclistdr)
self.len = len(self.picture_list)
def select_pic(self,i):
if i>=self.len:
print('retry, max len is {}'.format(len(self.len)))
else:
self.i = i
def show_area(self,x,xx,y,yy):
if not self.i:
self.i = 0
self.picture = self.picture_list[self.i]
self.area = self.picture[x:xx,y:yy,:]
plt.imshow(self.area)
def set_aim_area(self):
self.aim_area = self.area
def show_pic(self):
plt.imshow(self.picture)
def show_feature(self):
self.set_cv_parements()
self.aim_area_gray = cv2.cvtColor(self.aim_area, cv2.COLOR_BGR2GRAY)
self.aimkeypoints, self.aimdescriptor = self.orb.detectAndCompute(self.aim_area_gray , None)
# Create copies of the training image to draw our keypoints on
keyp_without_size = copy.copy(self.aim_area)
keyp_with_size = copy.copy(self.aim_area)
cv2.drawKeypoints(self.aim_area, self.aimkeypoints, keyp_without_size, color = (0, 255, 0))
cv2.drawKeypoints(self.aim_area, self.aimkeypoints, keyp_with_size, flags = cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# Display the image with the keypoints without size or orientation
plt.subplot(121)
plt.title('Keypoints Without Size or Orientation')
plt.imshow(keyp_without_size)
# Display the image with the keypoints with size and orientation
plt.subplot(122)
plt.title('Keypoints With Size and Orientation')
plt.imshow(keyp_with_size)
plt.show()
# Print the number of keypoints detected
print("\nNumber of keypoints Detected: ", len(self.aimkeypoints))
def serch_featrue(self,mid_step,thread):
dx,dy,cc = self.aim_area.shape
self.mid_step=mid_step
self.dx = dx
self.dy = dy
aa,bb,cc = self.picture.shape
xstep ,ystep= int((aa-dx)/mid_step),int((bb-dy)/mid_step)
self.anserlist=[]
for xs in range(xstep):
for ys in range(ystep):
query_image = self.picture[(xs)*self.mid_step:(xs)*self.mid_step+dx,
(ys)*self.mid_step:(ys)*self.mid_step+dy,:]
query_gray = cv2.cvtColor(query_image, cv2.COLOR_BGR2GRAY)
keypoints_query, descriptors_query = self.orb.detectAndCompute(query_gray, None)
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck = True)
try:
matches = bf.match(self.aimdescriptor, descriptors_query)
matches = sorted(matches, key = lambda x : x.distance)
#print(xs,ys)
if len(matches)>thread:
self.anserlist.append([xs,ys,len(matches)])
except:
pass
def plot_result(self):
for i,j in enumerate(self.anserlist[:30]):
xs,ys,i=j[0],j[1],i+1
ax = plt.subplot(5,6,i)
mid_step = self.mid_step
query_image = self.picture[(xs)*mid_step:(xs)*mid_step+self.dx,
(ys)*mid_step:(ys)*mid_step+self.dy,:]
query_gray = cv2.cvtColor(query_image, cv2.COLOR_BGR2GRAY)
ax.imshow(query_gray)
ax.set_title("location_{}_{}".format(xs,ys))
def set_cv_parements(self,mount=200,vec=1.3,edge=21,WTA=2,patch=10,fast=10):
self.orb = cv2.ORB_create(mount,vec,edgeThreshold = edge,
firstLevel = 0,
WTA_K = WTA,
patchSize = patch,
fastThreshold = fast)
def show(self,xs,ys,i):
ax = plt.subplot(5,6,i)
mid_step = self.mid_step
query_image = self.picture[(xs)*mid_step:(xs)*mid_step+dx,
(ys)*mid_step:(ys)*mid_step+dy,:]
query_gray = cv2.cvtColor(query_image, cv2.COLOR_BGR2GRAY)
ax.imshow(query_gray)
ax.set_title("location_{}_{}".format(xs,ys))
@staticmethod
def walkFile_F(file):
filelist = []
for root, dirs, files in os.walk(file):
for d in dirs:
filelist.append(os.path.join(root, d))
return filelist
@staticmethod
def walkFile_item(file):
piclist=[]
for root, dirs, files in os.walk(file):
for f in files:
piclist.append(os.path.join(root, f))
return piclist
@staticmethod
def read_picture(path):
picture_list = [cv2.imread(i) for i in path]
picture_list = [cv2.cvtColor(i,cv2.COLOR_BGR2RGB) for i in picture_list]
return picture_list
if __name__== "main":
score = Score()
score.upload_pic(r'C:\Users\86355\Desktop\score_detector\img_pdf')
score.select_pic(7)
score.show_area(360,480,355,405)
score.set_aim_area()
score.show_feature()A
score.select_pic(15)
score.serch_featrue(25,9)
score.aim_area.shape
%matplotlib qt5
print(len(score.anserlist))
score.plot_result()
nfeatures - int
確定要查找的功能(關(guān)鍵點(diǎn))的最大數(shù)量洽洁。
scaleFactor - float
金字塔抽取比率必須大于1.ORB使用圖像金字塔來(lái)查找要素,因此您必須提供金字塔中每層之間的比例因子和金字塔所具有的層數(shù)订晌。 scaleFactor = 2表示古典金字塔虏辫,每個(gè)下一個(gè)級(jí)別的像素比前一個(gè)像素少4倍。大比例因子將減少找到的功能數(shù)量锈拨。
nlevels - int
金字塔等級(jí)的數(shù)量砌庄。最小級(jí)別的線性大小等于input_image_linear_size / pow(scaleFactor,nlevels)奕枢。
edgeThreshold - - int
未檢測(cè)到要素的邊框的大小娄昆。由于關(guān)鍵點(diǎn)具有特定的像素大小,因此圖像的邊緣必須從搜索中排除缝彬。 edgeThreshold的大小應(yīng)該等于或大于patchSize參數(shù)萌焰。
firstLevel - int
此參數(shù)允許您確定哪個(gè)級(jí)別應(yīng)視為金字塔中的第一級(jí)。在當(dāng)前的實(shí)現(xiàn)中它應(yīng)該是0谷浅。通常扒俯,具有統(tǒng)一比例的金字塔等級(jí)被認(rèn)為是第一等級(jí)。
WTA_K - int
用于產(chǎn)生定向的BRIEF描述符的每個(gè)元素的隨機(jī)像素的數(shù)量一疯『承可能的值是2,3和4,其中2是默認(rèn)值墩邀。例如掌猛,3的值意味著一次選擇三個(gè)隨機(jī)像素來(lái)比較它們的亮度。最亮像素的索引被返回眉睹。由于有3個(gè)像素荔茬,返回的索引將為0,1或2只盹。
scoreType - int
該參數(shù)可以設(shè)置為HARRIS_SCORE或FAST_SCORE。默認(rèn)的HARRIS_SCORE表示Harris corner算法用于對(duì)要素進(jìn)行排名兔院。該分?jǐn)?shù)僅用于保留最佳功能殖卑。 FAST_SCORE產(chǎn)生的穩(wěn)定關(guān)鍵點(diǎn)稍低,但計(jì)算速度稍快坊萝。
patchSize - int
面向BRIEF描述符使用的補(bǔ)丁大小孵稽。當(dāng)然,在較小的金字塔層上十偶,由特征覆蓋的感知圖像區(qū)域?qū)⒏蟆?/p>
# Import copy to make copies of the training image
import copy
# Set the default figure size
plt.rcParams['figure.figsize'] = [14.0, 7.0]
# Set the parameters of the ORB algorithm by specifying the maximum number of keypoints to locate and
# the pyramid decimation ratio
orb = cv2.ORB_create(200, 2.0)
# Find the keypoints in the gray scale training image and compute their ORB descriptor.
# The None parameter is needed to indicate that we are not using a mask.
keypoints, descriptor = orb.detectAndCompute(training_gray, None)
# Create copies of the training image to draw our keypoints on
keyp_without_size = copy.copy(training_image)
keyp_with_size = copy.copy(training_image)
# Draw the keypoints without size or orientation on one copy of the training image
cv2.drawKeypoints(training_image, keypoints, keyp_without_size, color = (0, 255, 0))
"""
下面的方法就是把關(guān)鍵點(diǎn)以及范圍描述出來(lái)
"""
# Draw the keypoints with size and orientation on the other copy of the training image
cv2.drawKeypoints(training_image, keypoints, keyp_with_size, flags = cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# Display the image with the keypoints without size or orientation
plt.subplot(121)
plt.title('Keypoints Without Size or Orientation')
plt.imshow(keyp_without_size)
# Display the image with the keypoints with size and orientation
plt.subplot(122)
plt.title('Keypoints With Size and Orientation')
plt.imshow(keyp_with_size)
plt.show()
# Print the number of keypoints detected
print("\nNumber of keypoints Detected: ", len(keypoints))
cv2.BFMatcher(normType = cv2.NORM_L2,
crossCheck = false)
normType
指定用于確定匹配質(zhì)量的度量菩鲜。默認(rèn)情況下,normType = cv2.NORM_L2惦积,它測(cè)量?jī)蓚€(gè)描述符之間的距離接校。但是,對(duì)于由ORB創(chuàng)建的二進(jìn)制描述符狮崩,海明度量標(biāo)準(zhǔn)更適合蛛勉。漢明度量通過(guò)計(jì)算二進(jìn)制描述符之間的不相似位的數(shù)量來(lái)確定距離。當(dāng)使用WTA_K = 2創(chuàng)建ORB描述符時(shí)睦柴,選擇兩個(gè)隨機(jī)像素并在亮度上進(jìn)行比較诽凌。最亮像素的索引返回為0或1.這種輸出只占用1位,因此應(yīng)該使用cv2.NORM_HAMMING度量坦敌。另一方面侣诵,如果使用WTA_K = 3創(chuàng)建ORB描述符,則選擇三個(gè)隨機(jī)像素并在亮度上進(jìn)行比較狱窘。最亮像素的索引返回為0,1或2.這樣的輸出將占用2位杜顺,因此稱(chēng)為cv2.NORM_HAMMING2(2代表2位)的漢明距離的特殊變體應(yīng)該是代替使用。然后蘸炸,對(duì)于選擇的任何度量躬络,當(dāng)比較訓(xùn)練和查詢圖像中的關(guān)鍵點(diǎn)時(shí),具有較小度量(它們之間的距離)的對(duì)被認(rèn)為是最佳匹配幻馁。
crossCheck - bool
一個(gè)布爾變量洗鸵,可以設(shè)置為T(mén)rue或False越锈。交叉檢查對(duì)于消除錯(cuò)誤匹配非常有用仗嗦。通過(guò)兩次執(zhí)行匹配程序進(jìn)行交叉檢查。第一次將訓(xùn)練圖像中的關(guān)鍵點(diǎn)與查詢圖像中的關(guān)鍵點(diǎn)進(jìn)行比較;然而甘凭,第二次將查詢圖像中的關(guān)鍵點(diǎn)與訓(xùn)練圖像中的關(guān)鍵點(diǎn)進(jìn)行比較(即稀拐,比較是向后完成的)。當(dāng)啟用交叉檢查時(shí)丹弱,只有在訓(xùn)練圖像中的關(guān)鍵點(diǎn)A是查詢圖像中關(guān)鍵點(diǎn)B的最佳匹配(反之亦然)(即德撬,如果查詢圖像中的關(guān)鍵點(diǎn)B是訓(xùn)練圖像中的點(diǎn)A)铲咨。
# Set the default figure size
plt.rcParams['figure.figsize'] = [34.0, 34.0]
# Create a Brute Force Matcher object. We set crossCheck to True so that the BFMatcher will only return consistent
# pairs. Such technique usually produces best results with minimal number of outliers when there are enough matches.
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck = True)
# Perform the matching between the ORB descriptors of the training image and the query image
matches = bf.match(descriptors_train, descriptors_query)
# The matches with shorter distance are the ones we want. So, we sort the matches according to distance
matches = sorted(matches, key = lambda x : x.distance)
# Connect the keypoints in the training image with their best matching keypoints in the query image.
# The best matches correspond to the first elements in the sorted matches list, since they are the ones
# with the shorter distance. We draw the first 85 mathces and use flags = 2 to plot the matching keypoints
# without size or orientation.
result = cv2.drawMatches(training_gray, keypoints_train, query_gray, keypoints_query, matches[:85], query_gray, flags = 2)
# we display the image
plt.title('Best Matching Points', fontsize = 30)
plt.imshow(result)
plt.show()
# Print the number of keypoints detected in the training image
print("Number of Keypoints Detected In The Training Image: ", len(keypoints_train))
# Print the number of keypoints detected in the query image
print("Number of Keypoints Detected In The Query Image: ", len(keypoints_query))
# Print total number of matching Keypoints between the training and query images
print("\nNumber of Matching Keypoints Between The Training and Query Images: ", len(matches))
import cv2
import numpy as np
import matplotlib.pyplot as plt
import os
import copy
"""
使用順序:
upload_pic(path) 傳入文件夾路徑
select_pic(i) 選定第i個(gè)圖
show_pic() 查看此圖像
show_area(x,xx,y,yy) 展示圖片區(qū)域
set_aim_area() 將展示的區(qū)域設(shè)為目標(biāo)圖像
show_feature() 以默認(rèn)參數(shù)運(yùn)行ORB set_cv_parements()修改參數(shù)
serch_featrue() 在當(dāng)前圖片中搜索匹配
plot_result() 將搜索到的部分展示出來(lái)(最大30 張)
"""
class Score(object):
def upload_pic(self,path):
piclistdr=self.walkFile_item(path)
self.picture_list=self.read_picture(piclistdr)
self.len = len(self.picture_list)
def select_pic(self,i):
if i>=self.len:
print('retry, max len is {}'.format(len(self.len)))
else:
self.i = i
def show_area(self,x,xx,y,yy):
if not self.i:
self.i = 0
self.picture = self.picture_list[self.i]
self.area = self.picture[x:xx,y:yy,:]
plt.imshow(self.area)
def set_aim_area(self):
self.aim_area = self.area
def show_pic(self):
plt.imshow(self.picture)
def show_feature(self):
self.set_cv_parements()
self.aim_area_gray = cv2.cvtColor(self.aim_area, cv2.COLOR_BGR2GRAY)
self.aimkeypoints, self.aimdescriptor = self.orb.detectAndCompute(self.aim_area_gray , None)
# Create copies of the training image to draw our keypoints on
keyp_without_size = copy.copy(self.aim_area)
keyp_with_size = copy.copy(self.aim_area)
cv2.drawKeypoints(self.aim_area, self.aimkeypoints, keyp_without_size, color = (0, 255, 0))
cv2.drawKeypoints(self.aim_area, self.aimkeypoints, keyp_with_size, flags = cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# Display the image with the keypoints without size or orientation
plt.subplot(121)
plt.title('Keypoints Without Size or Orientation')
plt.imshow(keyp_without_size)
# Display the image with the keypoints with size and orientation
plt.subplot(122)
plt.title('Keypoints With Size and Orientation')
plt.imshow(keyp_with_size)
plt.show()
# Print the number of keypoints detected
print("\nNumber of keypoints Detected: ", len(self.aimkeypoints))
def serch_featrue(self,mid_step,thread):
dx,dy,cc = self.aim_area.shape
self.mid_step=mid_step
self.dx = dx
self.dy = dy
aa,bb,cc = self.picture.shape
xstep ,ystep= int((aa-dx)/mid_step),int((bb-dy)/mid_step)
self.anserlist=[]
for xs in range(xstep):
for ys in range(ystep):
query_image = self.picture[(xs)*self.mid_step:(xs)*self.mid_step+dx,
(ys)*self.mid_step:(ys)*self.mid_step+dy,:]
query_gray = cv2.cvtColor(query_image, cv2.COLOR_BGR2GRAY)
keypoints_query, descriptors_query = self.orb.detectAndCompute(query_gray, None)
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck = True)
try:
matches = bf.match(self.aimdescriptor, descriptors_query)
matches = sorted(matches, key = lambda x : x.distance)
#print(xs,ys)
if len(matches)>thread:
self.anserlist.append([xs,ys,len(matches)])
except:
pass
def plot_result(self):
for i,j in enumerate(self.anserlist[:30]):
xs,ys,i=j[0],j[1],i+1
ax = plt.subplot(5,6,i)
mid_step = self.mid_step
query_image = self.picture[(xs)*mid_step:(xs)*mid_step+self.dx,
(ys)*mid_step:(ys)*mid_step+self.dy,:]
query_gray = cv2.cvtColor(query_image, cv2.COLOR_BGR2GRAY)
ax.imshow(query_gray)
ax.set_title("location_{}_{}".format(xs,ys))
def set_cv_parements(self,mount=200,vec=1.3,edge=21,WTA=2,patch=10,fast=10):
self.orb = cv2.ORB_create(mount,vec,edgeThreshold = edge,
firstLevel = 0,
WTA_K = WTA,
patchSize = patch,
fastThreshold = fast)
def show(self,xs,ys,i):
ax = plt.subplot(5,6,i)
mid_step = self.mid_step
query_image = self.picture[(xs)*mid_step:(xs)*mid_step+dx,
(ys)*mid_step:(ys)*mid_step+dy,:]
query_gray = cv2.cvtColor(query_image, cv2.COLOR_BGR2GRAY)
ax.imshow(query_gray)
ax.set_title("location_{}_{}".format(xs,ys))
@staticmethod
def walkFile_F(file):
filelist = []
for root, dirs, files in os.walk(file):
for d in dirs:
filelist.append(os.path.join(root, d))
return filelist
@staticmethod
def walkFile_item(file):
piclist=[]
for root, dirs, files in os.walk(file):
for f in files:
piclist.append(os.path.join(root, f))
return piclist
@staticmethod
def read_picture(path):
picture_list = [cv2.imread(i) for i in path]
picture_list = [cv2.cvtColor(i,cv2.COLOR_BGR2RGB) for i in picture_list]
return picture_list
if __name__== "main":
score = Score()
score.upload_pic(r'C:\Users\86355\Desktop\score_detector\img_pdf')
score.select_pic(7)
score.show_area(360,480,355,405)
score.set_aim_area()
score.show_feature()A
score.select_pic(15)
score.serch_featrue(25,9)
score.aim_area.shape
%matplotlib qt5
print(len(score.anserlist))
score.plot_result()
切換其他片段:
修改參數(shù)后運(yùn)行
score.select_pic(15)
score.set_cv_parements(mount=200,vec=1.4,edge=15,WTA=2,patch=8,fast=15)
score.serch_featrue(25,15)
score.aim_area.shape
%matplotlib qt5
print(len(score.anserlist))
score.plot_result()
總結(jié)
單純使用ORB特征算法匹配效果勉強(qiáng),但是由于此類(lèi)圖像形狀單一蜓洪,默認(rèn)參數(shù)檢測(cè)不到特征纤勒,參數(shù)需要手工調(diào)整。對(duì)每一種類(lèi)型的符號(hào)這樣調(diào)整是不現(xiàn)實(shí)的隆檀。此算法在識(shí)譜中可以作為深度學(xué)習(xí)前期摇天,半自動(dòng)處理圖數(shù)據(jù)時(shí)作為篩選過(guò)濾器使用。