我正在使用Python 2.7.5和OpenCV 2.4.8
开发徽标分类器/识别器我有几个相同徽标的图像,但是使用不同的形式和演示文稿,我想用该信息训练分类器,并在最后恢复该徽标的名称,无论其形式或表现如何。
我想知道如何使用该信息训练KNN分类器,我有使用SURF提取关键点和描述符的代码,我将这些数据直接存储在硬盘上。
def FeatureDetector(cvImage=None, filename=None):
template = dict()
hessian_threshold = 5000
if(filename is not None):
inputImage = cv.imread(filename)
if(cvImage is not None):
inputImage = cvImage
imageGray = cv.cvtColor(inputImage, cv.COLOR_BGR2GRAY)
detector = cv.SURF(hessian_threshold)
keypoints, descriptors = detector.detectAndCompute(imageGray, None, useProvidedKeypoints = False)
template["image"] = inputImage
template["array"] = imageGray
template["keypoints"] = keypoints
template["descriptors"] = descriptors
return template
def saveKeypoints(filename, keypoints):
kArray = []
for point in keypoints:
keypoint = (point.pt, point.size, point.angle, point.response, point.octave, point.class_id)
kArray.append(keypoint)
with open(filename, "wb") as outputFile:
pickle.dump(kArray, outputFile)
return
def detection(logoName, extension, show=False):
imagePath = PATHS["logos"] + logoName + "/"
if(os.path.exists(imagePath)):
count = 1
while(True):
filename = imagePath + str(count) + "." + extension
if(not os.path.exists(filename)):
print "[!] File '%s' not found, the end of sequence was reached"%(filename)
break
temp = FeatureDetector(filename = filename)
saveKeypoints(PATHS["keypoints"] + inputName + "/" + str(count) + ".kp", temp["keypoints"])
np.save(PATHS["descriptors"] + inputName + "/" + str(count) + ".npy", temp["descriptors"])
np.save(PATHS["arrays"] + inputName + "/" + str(count) + ".npy", temp["array"])
if(show):
showFeatures(filename, temp)
print "[O] Processed '%s'"%(filename)
count += 1
else:
print "[X] Logo not found\n"
return
然后,我有另一个脚本加载数据并训练KNN但只有一种形式的徽标。我想用所有形式的徽标训练分类器,使用我拥有的所有关键点和描述符,只恢复一个结果。
def loadKeypoints(path):
keypoints = []
try:
with open(PATHS["keypoints"] + path + ".kp", "rb") as inputFile:
kArray = pickle.load(inputFile)
for point in kArray:
feature = cv.KeyPoint(
x=point[0][0],
y=point[0][1],
_size=point[1],
_angle=point[2],
_response=point[3],
_octave=point[4],
_class_id=point[5]
)
keypoints.append(feature)
except:
return False
return keypoints
def loadSURF():
global TEMPLATES, LOGOS
for logo in LOGOS:
TEMPLATES[logo] = list()
count = 1
while(True):
path = "%s/%d"%(logo, count)
keypoints = loadKeypoints(path)
if(not keypoints):
print "[!] Template for '%s' not found, the end of sequence was reached"%(path)
break
descriptors = np.load(PATHS["descriptors"] + path + ".npy")
array = np.load(PATHS["arrays"] + path + ".npy")
template = {
"keypoints": keypoints,
"descriptors": descriptors,
"array": array
}
print "[O] Template loaded from %s"%(path)
TEMPLATES[logo].append(template)
count += 1
return
def SURFCompare(temp, image):
samples = temp["descriptors"]
responses = np.arange(len(temp["keypoints"]), dtype=np.float32)
knn = cv.KNearest()
knn.train(samples, responses)
for template in TEMPLATES:
pattern = TEMPLATES[template]
for t in pattern:
for h, des in enumerate(t["descriptors"]):
des = np.array(des,np.float32).reshape((1,128))
retval, results, neigh_resp, dists = knn.find_nearest(des,1)
res, dist = int(results[0][0]), dists[0][0]
if dist < 0.1: # draw matched keypoints in red color
color = (0,0,255)
print template
else: # draw unmatched in blue color
color = (255,0,0)
#Draw matched key points on original image
x,y = temp["keypoints"][res].pt
center = (int(x),int(y))
cv.circle(image,center,2,color,-1)
return True
这可能吗?
KNN分类器是最接近的还是有其他更好的选择?我也在考虑使用FLANN匹配器。
我不知道它是否是最佳选择,因为实际上我只是在一种形式中识别一个徽标,但我希望能够识别出多个徽标中的多个徽标。
提前致谢。