Интеграция функции текстуры в обнаружение объектов на основе цвета для видеокадров

#python #numpy #opencv #image-processing #object-detection

#python #numpy #opencv #обработка изображений #обнаружение объектов

Вопрос:

Я работаю над проектом, в котором мне нужно обнаруживать цветные транспортные средства с высоты птичьего полета. Смотрите изображение-кадр ниже

транспортное средство

Поскольку я считаю, что в этом случае глубокое обучение является излишним, я решил использовать классический конвейер обнаружения, применив метод обратной проекции гистограммы для обнаружения красного транспортного средства.

Код, который я использую, показан ниже

 #import packages
import cv2 
import numpy as np
import matplotlib.pyplot as plt

#defining disk for the convolution
disc = cv2.getStructuringElement(cv2.MORPH_RECT,(10,10))
#defining Kernel
kernel=cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
kernel1 = np.ones((5,5),np.uint8)



#preparing the object model by cropping the target object and reading it
Red_Model=cv2.imread(r'C:/Users/kjbaili/.spyder-py3/webcam_calib/red_new_uniform.png')

#convert object_model to hsv
hsv_red =  cv2.cvtColor(Red_Model, cv2.COLOR_BGR2HSV)
cv2.imshow('HSV_Model',hsv_red)

#calculating histogram of object_model
M = cv2.calcHist([hsv_red],[0,1],None,[180,256],[0,180,0,256])

#reading the image where we want to search for the target object
img=cv2.imread(r'C:/Users/kjbaili/.spyder-py3/Mean_Shift/MST_with_3D_projection/messigray1.png')

#converting the image to hsv
hsv_img =  cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

#calculating histogram of image
I= cv2.calcHist([hsv_img],[0,1],None,[180,256],[0,180,0,256])

#calculating the ration histogram
R=M.copy() /I.copy()

#extracting the image channels
h,s,v = cv2.split(hsv_img.copy())


 
#backprojecting the R_red hist
B1 = R[h.ravel(),s.ravel()]

#reshaping the resulted vector into image and normalize the values between 0 and 1
B2=B1.reshape(hsv_img.copy().shape[:2])
B = np.minimum(B1.copy(),1)
B = B.reshape(hsv_img.copy().shape[:2])
 



#removing noises
open_B_red=cv2.morphologyEx(B.copy(),cv2.MORPH_OPEN,kernel)     
Filter_red=cv2.filter2D(open_B_red.copy(),-1,disc,open_B_red)

#displaying results
cv2.imshow('Filter',Filter_red)



cv2.waitKey(0)
cv2.destroyAllWindows()
  

Алгоритм работает для проиллюстрированного изображения (см. Изображение маски результата)
введите описание изображения здесь

Однако, когда цвета объекта совпадают с цветами фона, как на изображении ниже, он также обнаруживает мою футболку, он обнаруживает их оба и, таким образом, не распознает только целевой объект

сбой

Поэтому я подумал о использовании дополнительной функции наряду с функцией цвета для улучшения обнаружения, чтобы она все еще обнаруживала целевой объект, несмотря на небольшое сходство в цветах, и пришел к так называемому «Локальному двоичному шаблону-LBP«, который вычисляет текстуру объекта. На самом деле, я мог бы рассчитать LBP для объекта и изображения, однако не знаю, как интегрировать его с вышеуказанным методом, чтобы красный автомобиль обнаруживался с помощью обнаружения цвета и текстуры.

Поэтому я был бы очень признателен за идею о том, как улучшить обнаружение в таком случае, используядополнительные функции из LBP или даже другие дополнительные функции.

для получения информации о LBP, пожалуйста, смотрите:https://towardsdatascience.com/face-recognition-how-lbph-works-90ec258c3d6b

для получения информации о том, как работает обратная проекция гистограммы:https://theailearner.com/2019/04/18/histogram-backprojection /

Вот исходное изображение: изображение Вот полученная маска Маска заранее спасибо

Комментарии:

1. В чем разница между футболкой и автомобилем? 1. Автомобиль представляет собой прямоугольник с постоянным соотношением w / h (~ 2-2,5). 2. Автомобиль имеет выпуклую форму. Вы можете попробовать использовать эти свойства.

2. Спасибо за комментарий. Вы имеете в виду, что я говорю алгоритму искать прямоугольные формы в полученном изображении маски вместо всего остального? ? @AlexAlex

3. Получите контуры из изображения маски. Затем фильтруйте по соотношению сторон и площади.

4. .Спасибо за комментарий. . Не могли бы вы выразить это на примере? . @fmw42

5. Редко бывает, что ваша футболка будет иметь тот же аспект и область. Итак, протестируйте, используя комбинацию аспекта и области. Автомобили будут почти одинакового размера.

Ответ №1:

Вот один из способов сделать это в Python / OpenCV. Первый порог для цвета. Затем примените некоторую морфологию для очистки посторонних областей. Затем получите контуры и выполните цикл над каждым из них. Вычислите повернутый прямоугольник для каждого и его площадь и соотношение сторон (наибольшее измерение / наименьшее измерение). Отфильтруйте контуры в диапазоне обоих и нарисуйте белый контур и белый повернутый прямоугольник на входном изображении.

Ввод:

введите описание изображения здесь

 import cv2
import numpy as np

image = cv2.imread("red_car.png")
hh, ww = image.shape[:2]

# convert to HSV
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

# create a binary thresholded image
lower = (80,100,180)
upper = (255,255,255)
thresh = cv2.inRange(hsv, lower, upper)


# apply morphology
kernel = np.ones((5,5), np.uint8)
clean = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

# get external contours
contours = cv2.findContours(clean, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]

area_thresh1 = 500
area_thresh2 = 1000
aspect_thresh1 = 2
aspect_thresh2 = 4
result1 = image.copy()
result2 = image.copy()
for c in contours:
    
    # get rotated rectangle from contour
    # get its dimensions
    # get angle relative to horizontal from rotated rectangle
    rotrect = cv2.minAreaRect(c)
    box = cv2.boxPoints(rotrect)
    box = np.int0(box)
    (center), (dim1,dim2), angle = rotrect
    maxdim = max(dim1,dim2)
    mindim = min(dim1,dim2)
    area = dim1 * dim2
    if area > 0:
        aspect = maxdim / mindim
        #print(area, aspect)

    if area > area_thresh1 and area < area_thresh2 and aspect > aspect_thresh1 and aspect < aspect_thresh2:
        # draw contour on input
        cv2.drawContours(result1,[c],0,(255,255,255),1)
        # draw rectangle on input
        cv2.drawContours(result2,[box],0,(255,255,255),1)
        print(area, aspect)

# save result
cv2.imwrite("red_car_thresh.png",thresh)
cv2.imwrite("red_car_clean.png",clean)
cv2.imwrite("red_car_thresh_result1.png",result1)
cv2.imwrite("red_car_thresh_result2.png",result2)

# display result
cv2.imshow("thresh", thresh)
cv2.imshow("clean", clean)
cv2.imshow("result1", result1)
cv2.imshow("result2", result2)
cv2.waitKey(0)
cv2.destroyAllWindows()
  

Пороговое изображение:

введите описание изображения здесь

Изображение, очищенное от морфологии:

введите описание изображения здесь

Контур автомобиля:

введите описание изображения здесь

Ограничивающая рамка с поворотом автомобиля:

введите описание изображения здесь

Комментарии:

1. Спасибо, что это действительно работает. Однако, когда я тестировал это на видео, он не обнаруживает автомобиль с меткой времени cetrain. Я думаю, мне нужно настроить среднюю площадь и соотношение автомобилей во всем видео, чтобы заставить его работать. Был бы благодарен за голосование 🙂

2. Да, настройте пороговые значения по мере необходимости для масштаба изображений и типов транспортных средств.

Ответ №2:

Сопоставление шаблона с несколькими управляющими параметрами, такими как (размер .. и т.д.), Может работать для вашего случая :

 import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('Path_To_\target.jpg',0)
img2 = img.copy()
imgDisp = cv2.cvtColor(img2 , cv2.COLOR_GRAY2RGB)
template = cv2.imread('Path_t0\template.jpg',0)
w, h = template.shape[::-1]

# All the 6 methods for comparison in a list
methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
        'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']

for meth in methods:
    img = img2.copy()
    method = eval(meth)

    # Apply template Matching
    res = cv2.matchTemplate(img,template,method)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

    # If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum
    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
       top_left = min_loc
    else:
       top_left = max_loc
    bottom_right = (top_left[0]   w, top_left[1]   h)

    cv2.rectangle(imgDisp,top_left, bottom_right, 255, 2)

    plt.subplot(121),plt.imshow(res,cmap = 'gray')
    plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
    plt.subplot(122),plt.imshow(imgDisp,cmap = 'gray')
    plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
    plt.suptitle(meth)

    plt.show()
  

Результат :

Вы можете доработать код ЗДЕСЬ

введите описание изображения здесь

Комментарии:

1. Спасибо за ответ. Я уже пробовал сопоставлять шаблоны раньше. на самом деле i не работает хорошо, поскольку обнаруживает несколько областей, которые не имеют отношения к целевому объекту (транспортному средству). К вашему сведению, я работаю над видеокадрами, а не над неподвижным изображением. @Ziri