Я пытаюсь обнаружить некоторые объекты на картинке по их форме и цвету.
Это исходное изображение, и я хочу найти две розовые кружки (выделены зеленым)
Я использую цветовую маску, чтобы изолировать две кружки, и результат довольно хороший, как вы можете видеть здесь:
Проблема в том, что могут быть обнаружены и другие объекты с похожими цветами, например, красный стул в нижней правой части.
Я могу лучше настроить параметры цветовой маски... например, я могу более конкретно изолировать цвет, использовать расширение/эрозию для уменьшения шума. Но полагаться только на цвета не идеально, и это чревато ошибками. Например, если я просто слегка поверну стул, освещение на нем изменится, и я снова получу шум.
Чтобы сделать все немного более надежным, я пытался дополнительно выбрать кружки, используя их форму с cv2. приблизительноPolyDP, но мне часто не удается отделить кружку от шумных областей. Форма кружки, идентифицируемая по цветовой маске, часто бывает не очень точной, поэтому аппроксимирующий многоугольник может состоять из до 10 сегментов, что делает бесполезным его отделение от шума.
Это код, который я использую:
import cv2
import numpy as np
def main():
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
cv2.namedWindow("Color selection")
cv2.createTrackbar("Low_H", "Color selection", 114, 255, nothing)
cv2.createTrackbar("Low_S", "Color selection", 76, 255, nothing)
cv2.createTrackbar("Low_V", "Color selection", 145, 255, nothing)
cv2.createTrackbar("Up_H", "Color selection", 170, 255, nothing)
cv2.createTrackbar("Up_S", "Color selection", 255, 255, nothing)
cv2.createTrackbar("Up_V", "Color selection", 255, 255, nothing)
cv2.createTrackbar("N_erosion", "Color selection", 4, 50, nothing)
cv2.createTrackbar("epsilon", "Color selection", 2, 20, nothing)
cv2.createTrackbar("Area_min", "Color selection", 52, 500, nothing)
cv2.createTrackbar("Area_max", "Color selection", 1800, 4000, nothing)
while True:
ret, frame = cap.read()
frame_hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
frame_hsv_blur = cv2.GaussianBlur(frame_hsv, (7, 7), 0)
## parameters selection
l_h = cv2.getTrackbarPos("Low_H", "Color selection")
l_s = cv2.getTrackbarPos("Low_S", "Color selection")
l_v = cv2.getTrackbarPos("Low_V", "Color selection")
u_h = cv2.getTrackbarPos("Up_H", "Color selection")
u_s = cv2.getTrackbarPos("Up_S", "Color selection")
u_v = cv2.getTrackbarPos("Up_V", "Color selection")
N_erode = cv2.getTrackbarPos("N_erosion", "Color selection")
eps = cv2.getTrackbarPos("epsilon", "Color selection")/100
area_min = cv2.getTrackbarPos("Area_min", "Color selection")
area_max = cv2.getTrackbarPos("Area_max", "Color selection")
N_erode = N_erode if N_erode>0 else 1
lower_values = np.array([l_h, l_s, l_v])
upper_values = np.array([u_h, u_s, u_v])
mask = cv2.inRange(frame_hsv_blur, lower_values, upper_values)
kernel = np.ones((N_erode,N_erode), np.uint8)
mask = cv2.erode(mask, kernel)
## find contours in image based on color mask
contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
area = cv2.contourArea(contour)
perimeter = cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, eps*perimeter, True)
x,y,w,h = cv2.boundingRect(contour)
if (area_min < area < area_max) and (2<len(approx)):
x_0 = int(x+w/2)
y_0 = int(y+h/2)
frame = cv2.putText(frame, str(len(approx)), (x,y), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255,0,0), thickness=3)
frame = cv2.circle(frame, (x_0, y_0), 10, (255,255,50), -1)
cv2.imshow("tracking", frame)
cv2.imshow("mask", mask)
key = cv2.waitKey(1)
if key == ord('q'):
break
elif key == ord('s'):
cv2.imwrite("saved_image.jpg", frame)
cv2.destroyAllWindows()
cap.release()
def nothing(x):
pass
if __name__ == '__main__':
main()
Итак, опять же, мой главный вопрос касается обнаружения формы. Мне было интересно, могу ли я попробовать другой подход, чтобы лучше использовать тот факт, что я ищу очень специфическую форму, возможно, используя что-то еще, кроме cv2. приблизительноPolyDP. Какие-либо предложения?
cv2.inRange()
цветовые границы очень узкие, что не позволяет обнаружить рожу во всей красе. Здесь мы можем пойти на компромисс, мы можем ослабить верхнюю и нижнюю границы цвета, что, очевидно, теперь будет обнаруживать больше контуров. И затем вы можете отфильтровать их по площади и приблизительному PlyDp. - person ZdaR   schedule 21.07.2020