Получить возможности HOG-изображений из OpenCV + Python? - PullRequest
30 голосов
/ 22 мая 2011

Я прочитал этот пост о том, как использовать OpenCV HOG-детектор пешеходов: Как я могу обнаруживать и отслеживать людей, использующих OpenCV?

Я хочу использовать HOG для обнаружения других типов объектов на изображениях (не только пешеходов). Однако привязка Python HOGDetectMultiScale , похоже, не дает доступа к фактическим функциям HOG.

Есть ли способ использовать Python + OpenCV для извлечения функций HOG непосредственно из любого изображения?

Ответы [ 7 ]

145 голосов
/ 04 августа 2014

В python opencv вы можете вычислить свинью так:

 import cv2
 hog = cv2.HOGDescriptor()
 im = cv2.imread(sample)
 h = hog.compute(im)
39 голосов
/ 25 июня 2015

1. Получить встроенную документацию: Следующая команда на вашей консоли python поможет вам узнать структуру класса HOGDescriptor:

 import cv2; 
 help(cv2.HOGDescriptor())

2. Пример кода: Ниже приведен фрагмент кода для инициализации cv2.HOGDescriptor с другими параметрами (используемые здесь термины являются стандартными терминами, которые хорошо определены в документации OpenCV здесь ):

import cv2
image = cv2.imread("test.jpg",0)
winSize = (64,64)
blockSize = (16,16)
blockStride = (8,8)
cellSize = (8,8)
nbins = 9
derivAperture = 1
winSigma = 4.
histogramNormType = 0
L2HysThreshold = 2.0000000000000001e-01
gammaCorrection = 0
nlevels = 64
hog = cv2.HOGDescriptor(winSize,blockSize,blockStride,cellSize,nbins,derivAperture,winSigma,
                        histogramNormType,L2HysThreshold,gammaCorrection,nlevels)
#compute(img[, winStride[, padding[, locations]]]) -> descriptors
winStride = (8,8)
padding = (8,8)
locations = ((10,20),)
hist = hog.compute(image,winStride,padding,locations)

3. Причина: Результирующий дескриптор hog будет иметь размерность: 9 ориентаций X (4 угловых блока, которые получают 1 нормализацию + 6x4 блоков по краям, которые получают 2 нормализации + 6x6 блоков, которые получают 4 нормализации) = 1764. поскольку я дал только одно местоположение для hog.compute ().

4. Еще один способ инициализации - из xml-файла, который содержит все значения параметров:

hog = cv2.HOGDescriptor("hog.xml")

Чтобы получить XML-файл, можно сделать следующее:

hog = cv2.HOGDescriptor()
hog.save("hog.xml")

и отредактируйте соответствующие значения параметров в XML-файле.

10 голосов
/ 07 февраля 2017

Несмотря на то, что существует метод, как сказано в предыдущих ответах:

hog = cv2.HOGDescriptor ()

Я хотел бы опубликовать реализацию Python, которую выможно найти в каталоге примеров opencv, надеясь, что это может быть полезно для понимания функций HOG:

def hog(img):
    gx = cv2.Sobel(img, cv2.CV_32F, 1, 0)
    gy = cv2.Sobel(img, cv2.CV_32F, 0, 1)
    mag, ang = cv2.cartToPolar(gx, gy)
    bin_n = 16 # Number of bins
    bin = np.int32(bin_n*ang/(2*np.pi))

    bin_cells = []
    mag_cells = []

    cellx = celly = 8

    for i in range(0,img.shape[0]/celly):
        for j in range(0,img.shape[1]/cellx):
            bin_cells.append(bin[i*celly : i*celly+celly, j*cellx : j*cellx+cellx])
            mag_cells.append(mag[i*celly : i*celly+celly, j*cellx : j*cellx+cellx])   

    hists = [np.bincount(b.ravel(), m.ravel(), bin_n) for b, m in zip(bin_cells, mag_cells)]
    hist = np.hstack(hists)

    # transform to Hellinger kernel
    eps = 1e-7
    hist /= hist.sum() + eps
    hist = np.sqrt(hist)
    hist /= norm(hist) + eps

    return hist

С уважением.

10 голосов
/ 03 мая 2016

Вот решение, которое использует только OpenCV:

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

img = cv2.cvtColor(cv2.imread("/home/me/Downloads/cat.jpg"),
                   cv2.COLOR_BGR2GRAY)

cell_size = (8, 8)  # h x w in pixels
block_size = (2, 2)  # h x w in cells
nbins = 9  # number of orientation bins

# winSize is the size of the image cropped to an multiple of the cell size
hog = cv2.HOGDescriptor(_winSize=(img.shape[1] // cell_size[1] * cell_size[1],
                                  img.shape[0] // cell_size[0] * cell_size[0]),
                        _blockSize=(block_size[1] * cell_size[1],
                                    block_size[0] * cell_size[0]),
                        _blockStride=(cell_size[1], cell_size[0]),
                        _cellSize=(cell_size[1], cell_size[0]),
                        _nbins=nbins)

n_cells = (img.shape[0] // cell_size[0], img.shape[1] // cell_size[1])
hog_feats = hog.compute(img)\
               .reshape(n_cells[1] - block_size[1] + 1,
                        n_cells[0] - block_size[0] + 1,
                        block_size[0], block_size[1], nbins) \
               .transpose((1, 0, 2, 3, 4))  # index blocks by rows first
# hog_feats now contains the gradient amplitudes for each direction,
# for each cell of its group for each group. Indexing is by rows then columns.

gradients = np.zeros((n_cells[0], n_cells[1], nbins))

# count cells (border cells appear less often across overlapping groups)
cell_count = np.full((n_cells[0], n_cells[1], 1), 0, dtype=int)

for off_y in range(block_size[0]):
    for off_x in range(block_size[1]):
        gradients[off_y:n_cells[0] - block_size[0] + off_y + 1,
                  off_x:n_cells[1] - block_size[1] + off_x + 1] += \
            hog_feats[:, :, off_y, off_x, :]
        cell_count[off_y:n_cells[0] - block_size[0] + off_y + 1,
                   off_x:n_cells[1] - block_size[1] + off_x + 1] += 1

# Average gradients
gradients /= cell_count

# Preview
plt.figure()
plt.imshow(img, cmap='gray')
plt.show()

bin = 5  # angle is 360 / nbins * direction
plt.pcolor(gradients[:, :, bin])
plt.gca().invert_yaxis()
plt.gca().set_aspect('equal', adjustable='box')
plt.colorbar()
plt.show()

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

8 голосов
/ 14 ноября 2011

Если вам нужен быстрый код Python для функций HOG, я перенес код на Cython: https://github.com/cvondrick/pyvision/blob/master/vision/features.pyx

1 голос
/ 12 июля 2011

Я бы не согласился с аргументом пикксу.В конце концов, детектор HOG - это «просто» жесткий линейный фильтр.Любые степени свободы в «объекте» (то есть в людях) приводят к размытию в детекторе и фактически не обрабатываются им.Существует расширение этого детектора, использующее скрытые SVM, которые явно обрабатывают степени свободы, вводя структурные ограничения между независимыми частями (например, головой, руками и т. Д.), А также допускают многократное появление на объект (т. Е. Фронтальных людей и боковых людей)..).

Относительно детектора HOG в opencv: теоретически вы можете загрузить другой детектор для использования с функциями, но вы не можете получить сами функции.таким образом, если у вас есть обученный детектор (то есть линейный фильтр определенного класса), вы сможете загрузить его в детектор, чтобы получить быстродействие детектирования opencv.при этом должно быть легко взломать исходный код opencv, чтобы предоставить этот доступ, и предложить этот патч обратно сопровождающим.

0 голосов
/ 25 мая 2011

Я бы не рекомендовал использовать функции HOG для обнаружения других объектов, кроме пешеходов. В оригинальной статье HOG, написанной Далалом и Триггсом, они особо упомянули, что их детектор построен на основе обнаружения пешеходов, что позволяет ему получить значительные степени свободы в конечностях при использовании сильных структурных указаний вокруг человеческого тела.

Вместо этого попробуйте взглянуть на OpenCV HaarDetectObjects . Вы можете научиться тренировать свои собственные каскады здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...