python 定义模板和图像之间的旋转Angular

x33g5p2x  于 2024-01-05  发布在  Python
关注(0)|答案(1)|浏览(141)

一般来说,我的目标是让UV打印机在徽章上打印图像。有一些带有徽章的输入图像,我需要确定对象的位置,相对于模板的旋转,然后将打印图像应用到结果位置并将其旋转到所需的Angular 。第一阶段,识别图标的位置,是成功的。要做到这一点,我使用了HSV配色方案和饱和度层,然后使用了Canny边缘检测器,调用了一个函数来查找轮廓,并获得了图标的边界框。下面是使用OpenCV库的Python代码:

  1. import numpy as np
  2. from matplotlib import pyplot as plt
  3. import improclib
  4. import cv2 as cv
  5. import random as rng
  6. from z_final_lib import getOrientation
  7. # load the image, convert it to grayscale, and blur it slightly
  8. image = cv.imread('b2.jpg')
  9. gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
  10. toCanny = image
  11. toCanny = improclib.select_colorsp(toCanny, colorsp='sat')
  12. cv.imshow("Original", image)
  13. canny_output = cv.Canny(toCanny, 30, 250)
  14. canny_output = improclib.morph_op(canny_output, 'close', 3)
  15. cv.imshow("canny_output", canny_output)
  16. contours, hierarchy = cv.findContours(canny_output, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
  17. print('contours len = ', len(contours))
  18. sorted_cnt = sorted(contours, key=cv.contourArea, reverse=True)
  19. bx, by, w, h = cv.boundingRect(sorted_cnt[0])
  20. max_area = w * h
  21. print('max_area')
  22. print(max_area)
  23. external_contours = []
  24. min_area_ratio = 0.05
  25. # Область изображения.
  26. im_area = image.shape[0] * image.shape[1]
  27. for cnt in sorted_cnt:
  28. bx, by, w, h = cv.boundingRect(cnt)
  29. cnt_area = w * h
  30. print(cnt_area)
  31. # Удалите очень мелкие дефекты.
  32. if (1 - cnt_area / max_area) < 0.6:
  33. external_contours.append(cnt)
  34. contours = external_contours
  35. print('contours len = ', len(contours))
  36. filled_image = np.zeros_like(canny_output)
  37. for c in contours:
  38. cv.drawContours(filled_image, [c], 0, (255, 255, 255), -1)
  39. filled_image = improclib.morph_op(filled_image, 'open', 3)
  40. cv.imshow('+++', filled_image)
  41. rng.seed(12345)
  42. contours_poly = [None] * len(contours)
  43. boundRect = [None] * len(contours)
  44. centers = [None] * len(contours)
  45. radius = [None] * len(contours)
  46. for i, c in enumerate(contours):
  47. contours_poly[i] = cv.approxPolyDP(c, 3, True)
  48. boundRect[i] = cv.boundingRect(contours_poly[i])
  49. centers[i], radius[i] = cv.minEnclosingCircle(contours_poly[i])
  50. drawing = image.copy()
  51. for i in range(len(contours)):
  52. color = (rng.randint(0, 256), rng.randint(0, 256), rng.randint(0, 256))
  53. cv.drawContours(drawing, contours_poly, i, color)
  54. cv.rectangle(drawing, (int(boundRect[i][0]), int(boundRect[i][1])),
  55. (int(boundRect[i][0] + boundRect[i][2]), int(boundRect[i][1] + boundRect[i][3])), color, 2)
  56. cv.imshow('Contours', drawing)
  57. cv.waitKey()
  58. cv.destroyAllWindows()

字符串
得到了一个很好的结果:


但是接下来我需要确定图标相对于模板的旋转Angular 。但这是一个死胡同。徽章并不完全相同,有一些缺陷。我尝试了特征检测方法,但它们并没有给予期望的结果。图标被认为是不同的。下面是代码

  1. sift = cv.SIFT_create()
  2. kp = sift.detect(gray, None)
  3. img = cv.drawKeypoints(gray, kp, img)
  4. cv.imshow('sift_keypoints.jpg', img)


结果:



被收割的硬币

kuuvgm7e

kuuvgm7e1#

从附加的结果图像中,您的SIFT关键点都是相同大小的,半径非常小。您的图标(硬币)具有较粗糙的特征,因此跨越较小半径的SIFT特征将无法正确捕获细节。因此,请尝试增加描述符半径/大小。此外,您应该独立地为所有图标执行此操作,然后在它们之间运行RANSAC以找到旋转。

相关问题