scikit oriented hog feature example python image-processing opencv

oriented - Obtener características de imagen HOG de OpenCV+Python?



opencv python hog (7)

He leído esta publicación sobre cómo usar el detector de peatones basado en HOG de OpenCV: ¿Cómo puedo detectar y rastrear personas usando OpenCV?

Quiero usar HOG para detectar otros tipos de objetos en las imágenes (no solo los peatones). Sin embargo, el enlace de Python de HOGDetectMultiScale no parece dar acceso a las características reales de HOG.

¿Hay alguna forma de usar Python + OpenCV para extraer las características HOG directamente de cualquier imagen?


A pesar de que existe un método como se dijo en las respuestas anteriores:

hog = cv2.HOGDescriptor ()

Me gustaría publicar una implementación de python que pueda encontrar en el directorio de ejemplos de opencv, con la esperanza de que pueda ser útil para entender la funcionallidad de 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

Saludos.


Aquí hay una solución que usa solo 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()

Utilicé el cálculo y la visualización del descriptor HOG para comprender el diseño de los datos y vectorizar los bucles sobre los grupos.


En python opencv puedes calcular cerdo de esta manera:

import cv2 hog = cv2.HOGDescriptor() im = cv2.imread(sample) h = hog.compute(im)


No estoy de acuerdo con el argumento de peakxu. El detector HOG en el extremo es "solo" un filtro lineal rígido. cualquier grado de libertad en el "objeto" (es decir, las personas) conduce a borrado en el detector, y en realidad no lo maneja. Existe una extensión de este detector que utiliza SVM latentes que maneja explícitamente los grados de libertad al introducir restricciones estructurales entre partes independientes (es decir, cabeza, brazos, etc.) y permite múltiples apariencias por objeto (es decir, gente frontal y personas de lado). .).

Con respecto al detector HOG en opencv: En teoría, puede cargar otro detector para usar con las características, pero no puede obtener las características por sí mismo. por lo tanto, si tiene un detector capacitado (es decir, un filtro lineal específico de clase), debe poder cargarlo en el detector para obtener el rendimiento de detecciones rápidas de opencv. Dicho esto, debería ser fácil piratear el código fuente de opencv para proporcionar este acceso y proponer este parche nuevamente a los mantenedores.


No recomendaría usar HOG para detectar objetos que no sean peatones. En el documento HOG original de Dalal y Triggs, mencionaron específicamente que su detector se basa en la detección de peatones al permitir grados de libertad significativos en las extremidades mientras se utilizan fuertes indicaciones estructurales alrededor del cuerpo humano.

En su lugar, intente examinar los HaarDetectObjects de OpenCV. Puedes aprender cómo entrenar tus propias cascadas here .



1. Obtenga documentación integrada: Seguir el comando en su consola de python le ayudará a conocer la estructura de la clase HOGDescriptor:

import cv2; help(cv2.HOGDescriptor())

2. Código de ejemplo: Aquí hay un fragmento de código para inicializar un cv2.HOGDescriptor con diferentes parámetros (Los términos que utilicé aquí son términos estándar que están bien definidos en la documentación de OpenCV here ):

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. Razonamiento: el descriptor de cerdo resultante tendrá una dimensión como: 9 orientaciones X (4 bloques de esquina que obtienen 1 normalización + 6x4 bloques en los bordes que obtienen 2 normalizaciones + 6x6 bloques que obtienen 4 normalizaciones) = 1764. como he dado solo una ubicación para hog.compute ().

4. Una forma más de inicializar es desde el archivo xml que contiene todos los valores de parámetros:

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

Para obtener un archivo xml uno puede hacer lo siguiente:

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

y edite los valores respectivos de los parámetros en el archivo xml.