旋轉不變性:圖像旋轉時,所選特征不随圖像的旋轉而發生變化
LBP參考:
LBP紋理特征提取
灰階不變性-旋轉不變性
import numpy as np
from PIL import Image
import math
def LBP(src):
'''
:param src:灰階圖像
:rtype:灰階圖像
'''
src = np.array(src)
height = src.shape[0]
width = src.shape[1]
dst = src.copy()
lbp_value = np.zeros((1,8), dtype=np.uint8)
neighbours = np.zeros((1,8), dtype=np.uint8)
# height as row, width as column
for x in range(1, width-1):
for y in range(1, height-1):
neighbours[0, 0] = src[y - 1, x - 1]
neighbours[0, 1] = src[y - 1, x]
neighbours[0, 2] = src[y - 1, x + 1]
neighbours[0, 3] = src[y, x - 1]
neighbours[0, 4] = src[y, x + 1]
neighbours[0, 5] = src[y + 1, x - 1]
neighbours[0, 6] = src[y + 1, x]
neighbours[0, 7] = src[y + 1, x + 1]
center = src[y, x]
for i in range(8):
if neighbours[0, i] > center:
lbp_value[0, i] = 1
else:
lbp_value[0, i] = 0
lbp = lbp_value[0, 0] * 1 + lbp_value[0, 1] * 2 + lbp_value[0, 2] * 4 + lbp_value[0, 3] * 8 \
+ lbp_value[0, 4] * 16 + lbp_value[0, 5] * 32 + lbp_value[0, 6] * 64 + lbp_value[0, 0] * 128
dst[y, x] = lbp
dst = Image.fromarray(dst)
return dst
def circular_LBP(src, radius, n_points):
src = np.array(src)
height = src.shape[0]
width = src.shape[1]
dst = src.copy()
src.astype(dtype=np.float32)
dst.astype(dtype=np.float32)
neighbours = np.zeros((1, n_points), dtype=np.uint8)
lbp_value = np.zeros((1, n_points), dtype=np.uint8)
for x in range(radius, width - radius - 1):
for y in range(radius, height - radius - 1):
lbp = 0.
# 先計算共n_points個點對應的像素值,使用雙線性插值法
for n in range(n_points):
theta = float(2 * np.pi * n) / n_points
x_n = x + radius * np.cos(theta)
y_n = y - radius * np.sin(theta)
# 向下取整
x1 = int(math.floor(x_n))
y1 = int(math.floor(y_n))
# 向上取整
x2 = int(math.ceil(x_n))
y2 = int(math.ceil(y_n))
# 将坐标映射到0-1之間
tx = np.abs(x - x1)
ty = np.abs(y - y1)
# 根據0-1之間的x,y的權重計算公式計算權重
w1 = (1 - tx) * (1 - ty)
w2 = tx * (1 - ty)
w3 = (1 - tx) * ty
w4 = tx * ty
# 根據雙線性插值公式計算第k個采樣點的灰階值
neighbour = src[y1, x1] * w1 + src[y2, x1] * w2 + src[y1, x2] * w3 + src[y2, x2] * w4
neighbours[0, n] = neighbour
center = src[y, x]
for n in range(n_points):
if neighbours[0, n] > center:
lbp_value[0, n] = 1
else:
lbp_value[0, n] = 0
for n in range(n_points):
lbp += lbp_value[0, n] * 2**n
# 轉換到0-255的灰階空間,比如n_points=16位時結果會超出這個範圍,對該結果歸一化
dst[y, x] = int(lbp / (2**n_points-1) * 255)
dst = Image.fromarray(dst)
return dst
def value_rotation(num):
value_list = np.zeros((8), np.uint8)
temp = int(num)
value_list[0] = temp
for i in range(7):
temp = ((temp << 1) | (temp / 128)) % 256
value_list[i+1] = temp
#print value_list
return np.min(value_list)
def rotation_invariant_LBP(src):
src = np.array(src)
height = src.shape[0]
width = src.shape[1]
dst = src.copy()
lbp_value = np.zeros((1, 8), dtype=np.uint8)
neighbours = np.zeros((1, 8), dtype=np.uint8)
for x in range(1, width - 1):
for y in range(1, height - 1):
neighbours[0, 0] = src[y - 1, x - 1]
neighbours[0, 1] = src[y - 1, x]
neighbours[0, 2] = src[y - 1, x + 1]
neighbours[0, 3] = src[y, x - 1]
neighbours[0, 4] = src[y, x + 1]
neighbours[0, 5] = src[y + 1, x - 1]
neighbours[0, 6] = src[y + 1, x]
neighbours[0, 7] = src[y + 1, x + 1]
center = src[y, x]
for i in range(8):
if neighbours[0, i] > center:
lbp_value[0, i] = 1
else:
lbp_value[0, i] = 0
lbp = lbp_value[0, 0] * 1 + lbp_value[0, 1] * 2 + lbp_value[0, 2] * 4 + lbp_value[0, 3] * 8 \
+ lbp_value[0, 4] * 16 + lbp_value[0, 5] * 32 + lbp_value[0, 6] * 64 + lbp_value[0, 0] * 128
# 旋轉不變值
dst[y, x] = value_rotation(lbp)
dst = Image.fromarray(dst)
return dst
if __name__ == '__main__':
I = Image.open('./test/130014.jpg').convert('L')
I.show()
I_lbp = LBP(I)
I_lbp.show()
I_lbp_circle = circular_LBP(I, 2, 16)
I_lbp_circle.show()
I_lbp_rotate_invariant = rotation_invariant_LBP(I)
I_lbp_rotate_invariant.show()
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TP31EerpmTzkkeNBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLyATOxMDOzcTM0IDNwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)