У меня есть проект компьютерного зрения дронов, над которым я работаю, с ограничением по времени в 0,05 секунды.По сути, мне нужно обнаружить оранжевую квадратную платформу с наилучшим квадратом.Прямо сейчас я использую openCV backprojection + findContours + ConvexHull.Это работает, но это слишком медленно (около 0,1 секунды).Любые другие алгоритмы или лучшие идеи?Должен ли я попробовать реализовать функцию findContour самостоятельно?
Вот мой код:
import cv2
import numpy as np
import time
import math
# creates region of interest histogram
roi = cv2.imread("./images/roi.jpeg")
roi_hsv = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
bin_size = 3
roi_hist = cv2.calcHist([roi_hsv], [0, 1], None, [bin_size, bin_size], [0, 256, 0, 256])
cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)
# returns mask of image after backprojection + thresholding
def backproject(image, roi_hist):
image_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
mask = cv2.calcBackProject([image_hsv], [0, 1], roi_hist, [0, 256, 0, 256], 1)
_, mask = cv2.threshold(mask, 254, 255, cv2.THRESH_BINARY)
return mask
"""
# test image
image = cv2.imread("./images/img3.jpeg")
image = cv2.resize(image, (600, 600))
mask = backproject(image, roi_hist)
_, contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key=cv2.contourArea)
cnt = contours[-1] # selects biggest contour
# hull = cv2.convexHull(cnt) # creates convex hull
M = cv2.moments(cnt)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
cntX = cnt[:,0,0]
cntY = cnt[:,0,1]
radii = np.sqrt((cntX - cX) ** 2 + (cntY - cY) ** 2)
min_radius = int(sorted(radii)[0])
print(min_radius)
cv2.circle(image, (cX, cY), 2, (0, 255, 255), 3)
cv2.circle(image, (cX, cY), min_radius, (0, 255, 255), 3)
cv2.drawContours(image, [cnt], 0, (255,0,255), 3)
cv2.imshow('image', image)
cv2.waitKey(0)
"""
# for webcam
cap = cv2.VideoCapture(0)
while(True):
start_time = time.time()
_, frame = cap.read()
frame = cv2.resize(frame, (800, 600))
mask = backproject(frame, roi_hist)
_, contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key=cv2.contourArea)
cnt = contours[-1] # selects biggest contour
cnt = cv2.convexHull(cnt)
M = cv2.moments(cnt)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
cntX = cnt[:,0,0]
cntY = cnt[:,0,1]
radii = np.sqrt((cntX - cX) ** 2 + (cntY - cY) ** 2)
min_radius = int(sorted(radii)[0])
cv2.circle(frame, (cX, cY), 2, (0, 255, 255), 3)
cv2.circle(frame, (cX, cY), min_radius, (0, 255, 255), 3)
cv2.drawContours(frame, [cnt], 0, (255, 0, 255), 3)
cv2.imshow('image', frame)
end_time = time.time()
print(end_time - start_time)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Вот пример изображения
позвольте мне указатьэто явно не квадрат.В настоящее время я просто пытаюсь получить определение контура, и все настроено и надежно.Моя конечная цель - найти положение xy и ориентацию наиболее подходящего квадрата, вписанного в платформу.