使用OpenCV Python的几个示例训练KNN分类器

时间:2014-01-28 21:37:40

标签: python opencv feature-detection surf feature-extraction

我正在使用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匹配器。

我不知道它是否是最佳选择,因为实际上我只是在一种形式中识别一个徽标,但我希望能够识别出多个徽标中的多个徽标。

提前致谢。

0 个答案:

没有答案