np.ndarray 存储 cells
import cv2
import numpy as np
np.set_printoptions(threshold=np.nan, linewidth=1000000)
# 向量长度: 9*4*7*15 = 3780
x_pixel = 128
y_pixel = 64
# 1 block = 4 cells
cell_w = 8
# block 窗口移动步长
step = 8
# 分成 8*8 cell
cell_x = int(x_pixel / cell_w) # 128/8=16
cell_y = int(y_pixel / cell_w) # 64/8=8
# 将 128*64 的矩阵 分成 8*8 的 cells
def div_cells(mag):
mag_cells = np.zeros(shape=(cell_x, cell_y, cell_w, cell_w)) # 8*8 cells 一共 cell_x * cell_y 个
# 沿 x轴 等分
mag_x = np.split(mag, cell_x, axis=0)
for i, l in enumerate(mag_x):
# 沿 x轴 分割的 list 转成 ndarray 后 再沿着 y轴 等分
mag_x[i] = np.array(l)
mag_xy = np.split(mag_x[i], cell_y, axis=1)
for j, l1 in enumerate(mag_xy):
mag_xy[j] = np.array(l1)
mag_cells[i][j] = mag_xy[j]
return mag_cells
# mag_cell, ang_cell 都是 np.ndarray
def get_bins(mag_cell, ang_cell):
# 直方图分为9个角度
bin_num = 9
bins = [0.0] * bin_num # 创建一个长度为 bin_num 的实数 list
offset = 20
mag_list = mag_cell.flatten()
ang_list = ang_cell.flatten()
# enumerate 对 list 中每个元素加个序号
# i 序号,ang 角度值
for i, ang in enumerate(ang_list):
if ang >= 180:
ang -= 180 # 有向转无向 [0, 180]
left_bin = int(ang / offset)
right_bin = left_bin + 1 if left_bin != bin_num - 1 else 0
# 对应一个 left < ang < right 求其 左右占比
# 离左越近 占左比越高
right_ratio = ang / offset - left_bin
left_ration = 1 - right_ratio
# 统计角度下的 权值 即 梯度幅值 按比划分左右
# 求得的 bins 是 9维
bins[left_bin] = mag_list[i] * left_ration
bins[right_bin] = mag_list[i] * right_ratio
return bins
def hog(img):
gx = cv2.Sobel(img, ddepth=cv2.CV_32F, dx=1, dy=0)
gy = cv2.Sobel(img, ddepth=cv2.CV_32F, dx=0, dy=1)
# 幅值 角度 ndarray 类型
mag, ang = cv2.cartToPolar(gx, gy, angleInDegrees=True) # gx,gy 必须是实数类型
ang = np.where(ang >= 180, ang - 180, ang) # ang 转到[0-180)
# 分割 mag ang 成 cells
# 每个 cell_list 中 的 每个元素 都是一个 cell 的 二维 list
mag_cells = div_cells(mag)
ang_cells = div_cells(ang)
hist = []
# 遍历添加 一个 block 里的 4个 cells
for x in range(cell_x - 1): # 16
for y in range(cell_y - 1): # 8
# 添加1个block里的4个cells
hist.extend(get_bins(mag_cells[x][y], ang_cells[x][y]))
hist.extend(get_bins(mag_cells[x][y + 1], ang_cells[x][y + 1]))
hist.extend(get_bins(mag_cells[x + 1][y], ang_cells[x + 1][y])) # 添加下一行的2个cell
hist.extend(get_bins(mag_cells[x + 1][y + 1], ang_cells[x + 1][y + 1]))
return np.array(hist)
src = cv2.imread('/Users/shuai/PycharmProjects/CatClassifier/cat1/0.jpg', flags=cv2.IMREAD_GRAYSCALE)
tmp = hog(src)
print(tmp)
print(tmp.shape)
List 存储 cells
import cv2
import numpy as np
np.set_printoptions(threshold=np.nan, linewidth=10000)
# 向量长度: 9*4*7*15 = 3780
x_pixel = 128
y_pixel = 64
# 1 block = 4 cells
cell_w = 8
# block 窗口移动步长
step = 8
# 分成 8*8 cell
cell_x = int(x_pixel / cell_w) # 128/8=16
cell_y = int(y_pixel / cell_w) # 64/8=8
# 将 128*64 的矩阵 分成 8*8 的 cells
def div_cells(mag):
cell_list = []
# 沿 x轴 等分
mag_x = np.split(mag, cell_x, axis=0)
for i, l in enumerate(mag_x):
# 沿 x轴 分割的 list 转成 ndarray 后 再沿着 y轴 等分
mag_x[i] = np.array(l)
mag_xy = np.split(mag_x[i], cell_y, axis=1)
for j in mag_xy:
cell_list.append(j)
return cell_list
def get_bins(mag_cell, ang_cell):
# 直方图分为9个角度
bin_num = 9
bins = [0.0] * bin_num # 创建一个长度为 bin_num 的实数 list
offset = 20
mag_list = mag_cell.flatten()
ang_list = ang_cell.flatten()
# enumerate 对 list 中每个元素加个序号
# i 序号,ang 角度值
for i, ang in enumerate(ang_list):
if ang >= 180:
ang -= 180 # 有向转无向 [0, 180]
left_bin = int(ang / offset)
right_bin = left_bin + 1 if left_bin != bin_num - 1 else 0
# 对应一个 left < ang < right 求其 左右占比
# 离左越近 占左比越高
right_ratio = ang / offset - left_bin
left_ration = 1 - right_ratio
# 统计角度下的 权值 即 梯度幅值 按比划分左右
# 求得的 bins 是 9维
bins[left_bin] = mag_list[i] * left_ration
bins[right_bin] = mag_list[i] * right_ratio
return bins
def hog(img):
gx = cv2.Sobel(img, ddepth=cv2.CV_32F, dx=1, dy=0)
gy = cv2.Sobel(img, ddepth=cv2.CV_32F, dx=0, dy=1)
# 幅值 角度 ndarray 类型
mag, ang = cv2.cartToPolar(gx, gy, angleInDegrees=True) # gx,gy 必须是实数类型
ang = np.where(ang >= 180, ang - 180, ang) # ang 转到[0-180)
# 分割 mag ang 成 cells
# 每个 cell_list 中 的 每个元素 都是一个 cell 的 二维 list
mag_cells = div_cells(mag)
ang_cells = div_cells(ang)
hist = []
# 遍历添加 一个 block 里的 4个 cells
for x in range(cell_x - 1): # 16
for y in range(cell_y - 1): # 8
# 添加1个block里的4个cells
hist.extend(get_bins(mag_cells[x], ang_cells[y]))
hist.extend(get_bins(mag_cells[x], ang_cells[y + 1]))
hist.extend(get_bins(mag_cells[x + cell_y], ang_cells[y])) # 添加下一行的2个cell
hist.extend(get_bins(mag_cells[x + cell_y], ang_cells[y + 1]))
return hist
src = cv2.imread('/Users/shuai/PycharmProjects/CatClassifier/cat1/0.jpg', flags=cv2.IMREAD_GRAYSCALE)
tmp = hog(src)
print(tmp)
print(tmp.__len__())