图像颜色特征
调用def color_moments函数提取图像颜色特征(hsv)
程序流程:
1.读取图像
2.RGB空间转换为HSV空间
3.初始化颜色特征
4.获取一阶矩(均值 mean)并放置在特征数组
5.获取二阶矩 (标准差 std)并放置在特征数组
6.三阶矩 (斜度 skewness)并放置在特征数组
import cv2
import numpy as np
def color_moments(img):
# img = cv2.imread(filename)
if img is None:
return
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)
color_feature = []
h_mean = np.mean(h) # np.sum(h)/float(N)
s_mean = np.mean(s) # np.sum(s)/float(N)
v_mean = np.mean(v) # np.sum(v)/float(N)
color_feature.extend([h_mean, s_mean, v_mean])
h_std = np.std(h) # np.sqrt(np.mean(abs(h - h.mean())**2))
s_std = np.std(s) # np.sqrt(np.mean(abs(s - s.mean())**2))
v_std = np.std(v) # np.sqrt(np.mean(abs(v - v.mean())**2))
color_feature.extend([h_std, s_std, v_std])
h_skewness = np.mean(abs(h - h.mean()) ** 3)
s_skewness = np.mean(abs(s - s.mean()) ** 3)
v_skewness = np.mean(abs(v - v.mean()) ** 3)
h_thirdMoment = h_skewness ** (1. / 3)
s_thirdMoment = s_skewness ** (1. / 3)
v_thirdMoment = v_skewness ** (1. / 3)
color_feature.extend([h_thirdMoment, s_thirdMoment, v_thirdMoment])
return color_feature
if __name__ == '__main__':
img = cv2.imread("2.jpg")
color_data = color_moments(img)
print(color_data)
—————————————————————————————————————————————————————————————————
—————————————————————————————————————————————————————————————————
灰度共生矩阵
1.定义灰度共生矩阵
2.定义八小类灰度共生矩阵
fast_glcm_mean(img)
fast_glcm_std(img)
fast_glcm_contrast(img)
fast_glcm_dissimilarity(img)
fast_glcm_homogeneity(img)
fast_glcm_ASM(img)
fast_glcm_max(img)
fast_glcm_entropy(img)
3.读取图像并获取H和W值
4.计算八小类灰度共生矩阵
import numpy as np
import cv2
from skimage import data
def fast_glcm(img):
vmin = 0
vmax = 255
nbit = 8
kernel_size = 5
mi, ma = vmin, vmax
ks = kernel_size
h,w = img.shape
# digitize
bins = np.linspace(mi, ma+1, nbit+1)
gl1 = np.digitize(img, bins) - 1
gl2 = np.append(gl1[:,1:], gl1[:,-1:], axis=1)
# make glcm
glcm = np.zeros((nbit, nbit, h, w), dtype=np.uint8)
for i in range(nbit):
for j in range(nbit):
mask = ((gl1==i) & (gl2==j))
glcm[i,j, mask] = 1
kernel = np.ones((ks, ks), dtype=np.uint8)
for i in range(nbit):
for j in range(nbit):
glcm[i,j] = cv2.filter2D(glcm[i,j], -1, kernel)
glcm = glcm.astype(np.float32)
return glcm
def fast_glcm_mean(img):
'''
calc glcm mean
'''
nbit = 8
h,w = img.shape
glcm = fast_glcm(img)
mean = np.zeros((h,w), dtype=np.float32)
for i in range(nbit):
for j in range(nbit):
mean += glcm[i,j] * i / (nbit)**2
return mean
def fast_glcm_std(img):
'''
calc glcm std
'''
nbit = 8
h,w = img.shape
glcm = fast_glcm(img)
mean = np.zeros((h,w), dtype=np.float32)
for i in range(nbit):
for j in range(nbit):
mean += glcm[i,j] * i / (nbit)**2
std2 = np.zeros((h,w), dtype=np.float32)
for i in range(nbit):
for j in range(nbit):
std2 += (glcm[i,j] * i - mean)**2
std = np.sqrt(std2)
return std
def fast_glcm_contrast(img):
'''
calc glcm contrast
'''
nbit = 8
h,w = img.shape
glcm = fast_glcm(img)
cont = np.zeros((h,w), dtype=np.float32)
for i in range(nbit):
for j in range(nbit):
cont += glcm[i,j] * (i-j)**2
return cont
def fast_glcm_dissimilarity(img):
'''
calc glcm dissimilarity
'''
nbit = 8
h,w = img.shape
glcm = fast_glcm(img)
diss = np.zeros((h,w), dtype=np.float32)
for i in range(nbit):
for j in range(nbit):
diss += glcm[i,j] * np.abs(i-j)
return diss
def fast_glcm_homogeneity(img):
'''
calc glcm homogeneity
'''
nbit = 8
h,w = img.shape
glcm = fast_glcm(img )
homo = np.zeros((h,w), dtype=np.float32)
for i in range(nbit):
for j in range(nbit):
homo += glcm[i,j] / (1.+(i-j)**2)
return homo
def fast_glcm_ASM(img):
'''
calc glcm asm, energy
'''
nbit = 8
h,w = img.shape
glcm = fast_glcm(img )
asm = np.zeros((h,w), dtype=np.float32)
for i in range(nbit):
for j in range(nbit):
asm += glcm[i,j]**2
ene = np.sqrt(asm)
return asm, ene
def fast_glcm_max(img):
'''
calc glcm max
'''
glcm = fast_glcm(img )
max_ = np.max(glcm, axis=(0,1))
return max_
def fast_glcm_entropy(img):
'''
calc glcm entropy
'''
ks = 5
glcm = fast_glcm(img )
pnorm = glcm / np.sum(glcm, axis=(0,1)) + 1./ks**2
ent = np.sum(-pnorm * np.log(pnorm), axis=(0,1))
return ent
if __name__ == '__main__':
img = data.camera() #
h,w = img.shape
glcm_mean = fast_glcm_mean(img)
print(glcm_mean)
glcm_std = fast_glcm_std(img)
print(glcm_std)
glcm_contrast = fast_glcm_contrast(img)
print(glcm_contrast)
glcm_dissimilarity = fast_glcm_dissimilarity(img)
print(glcm_dissimilarity)
glcm_homogeneity = fast_glcm_homogeneity(img)
print(glcm_homogeneity)
glcm_ASM = fast_glcm_ASM(img)
print(glcm_ASM)
glcm_max = fast_glcm_max(img)
print(glcm_max)
glcm_entropy = fast_glcm_entropy(img)
print(glcm_entropy)
—————————————————————————————————————————————————————————————————
—————————————————————————————————————————————————————————————————
LBP特征:
1.revolve_map为旋转不变模式的36种特征值从小到大进行序列化编号得到的字典
2.uniform_map为等价模式的58种特征值从小到大进行序列化编号得到的字典
3.将图像载入,并转化为灰度图,获取图像灰度图的像素信息
4.图像的LBP原始特征计算算法:将图像指定位置的像素与周围8个像素比较
5.比中心像素大的点赋值为1,比中心像素小的赋值为0,返回得到的二进制序列
6.获取值r的二进制中1的位数
import cv2
from PIL import Image
from pylab import *
class LBP:
def __init__(self):
self.revolve_map = {0: 0, 1: 1, 3: 2, 5: 3, 7: 4, 9: 5, 11: 6, 13: 7, 15: 8, 17: 9, 19: 10, 21: 11, 23: 12,
25: 13, 27: 14, 29: 15, 31: 16, 37: 17, 39: 18, 43: 19, 45: 20, 47: 21, 51: 22, 53: 23,
55: 24,
59: 25, 61: 26, 63: 27, 85: 28, 87: 29, 91: 30, 95: 31, 111: 32, 119: 33, 127: 34, 255: 35}
self.uniform_map = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 6: 5, 7: 6, 8: 7, 12: 8,
14: 9, 15: 10, 16: 11, 24: 12, 28: 13, 30: 14, 31: 15, 32: 16,
48: 17, 56: 18, 60: 19, 62: 20, 63: 21, 64: 22, 96: 23, 112: 24,
120: 25, 124: 26, 126: 27, 127: 28, 128: 29, 129: 30, 131: 31, 135: 32,
143: 33, 159: 34, 191: 35, 192: 36, 193: 37, 195: 38, 199: 39, 207: 40,
223: 41, 224: 42, 225: 43, 227: 44, 231: 45, 239: 46, 240: 47, 241: 48,
243: 49, 247: 50, 248: 51, 249: 52, 251: 53, 252: 54, 253: 55, 254: 56,
255: 57}
def describe(self, image):
image_array = np.array(Image.open(image).convert('L'))
return image_array
def calute_basic_lbp(self, image_array, i, j):
sum = []
if image_array[i - 1, j - 1] > image_array[i, j]:
sum.append(1)
else:
sum.append(0)
if image_array[i - 1, j] > image_array[i, j]:
sum.append(1)
else:
sum.append(0)
if image_array[i - 1, j + 1] > image_array[i, j]:
sum.append(1)
else:
sum.append(0)
if image_array[i, j - 1] > image_array[i, j]:
sum.append(1)
else:
sum.append(0)
if image_array[i, j + 1] > image_array[i, j]:
sum.append(1)
else:
sum.append(0)
if image_array[i + 1, j - 1] > image_array[i, j]:
sum.append(1)
else:
sum.append(0)
if image_array[i + 1, j] > image_array[i, j]:
sum.append(1)
else:
sum.append(0)
if image_array[i + 1, j + 1] > image_array[i, j]:
sum.append(1)
else:
sum.append(0)
return sum
def get_min_for_revolve(self, arr):
values = []
circle = arr
circle.extend(arr)
for i in range(0, 8):
j = 0
sum = 0
bit_num = 0
while j < 8:
sum += circle[i + j] << bit_num
bit_num += 1
j += 1
values.append(sum)
return min(values)
def calc_sum(self, r):
num = 0
while (r):
r &= (r - 1)
num += 1
return num
# 获取图像的LBP原始模式特征
def lbp_basic(self, image_array):
basic_array = np.zeros(image_array.shape, np.uint8)
width = image_array.shape[0]
height = image_array.shape[1]
for i in range(1, width - 1):
for j in range(1, height - 1):
sum = self.calute_basic_lbp(image_array, i, j)
bit_num = 0
result = 0
for s in sum:
result += s << bit_num
bit_num += 1
basic_array[i, j] = result
return basic_array
# 获取图像的LBP旋转不变模式特征
def lbp_revolve(self, image_array):
revolve_array = np.zeros(image_array.shape, np.uint8)
width = image_array.shape[0]
height = image_array.shape[1]
for i in range(1, width - 1):
for j in range(1, height - 1):
sum = self.calute_basic_lbp(image_array, i, j)
revolve_key = self.get_min_for_revolve(sum)
revolve_array[i, j] = self.revolve_map[revolve_key]
return revolve_array
# 获取图像的LBP等价模式特征
def lbp_uniform(self, image_array):
uniform_array = np.zeros(image_array.shape, np.uint8)
basic_array = self.lbp_basic(image_array)
width = image_array.shape[0]
height = image_array.shape[1]
for i in range(1, width - 1):
for j in range(1, height - 1):
k = basic_array[i, j] << 1
if k > 255:
k = k - 255
xor = basic_array[i, j] ^ k
num = self.calc_sum(xor)
if num <= 2:
uniform_array[i, j] = self.uniform_map[basic_array[i, j]]
else:
uniform_array[i, j] = 58
return uniform_array
# 获取图像的LBP旋转不变等价模式特征
def lbp_revolve_uniform(self, image_array):
uniform_revolve_array = np.zeros(image_array.shape, np.uint8)
basic_array = self.lbp_basic(image_array)
width = image_array.shape[0]
height = image_array.shape[1]
for i in range(1, width - 1):
for j in range(1, height - 1):
k = basic_array[i, j] << 1
if k > 255:
k = k - 255
xor = basic_array[i, j] ^ k
num = self.calc_sum(xor)
if num <= 2:
uniform_revolve_array[i, j] = self.calc_sum(basic_array[i, j])
else:
uniform_revolve_array[i, j] = 9
return uniform_revolve_array
# 绘制指定维数和范围的图像灰度归一化统计直方图
def show_hist(self, img_array, im_bins, im_range):
hist = cv2.calcHist([img_array], [0], None, im_bins, im_range)
hist = cv2.normalize(hist, None).flatten()
plt.plot(hist, color='r')
plt.xlim(im_range)
plt.show()
# 绘制图像原始LBP特征的归一化统计直方图
def show_basic_hist(self, img_array):
self.show_hist(img_array, [256], [0, 256])
# 绘制图像旋转不变LBP特征的归一化统计直方图
def show_revolve_hist(self, img_array):
self.show_hist(img_array, [36], [0, 36])
# 绘制图像等价模式LBP特征的归一化统计直方图
def show_uniform_hist(self, img_array):
self.show_hist(img_array, [60], [0, 60])
# 绘制图像旋转不变等价模式LBP特征的归一化统计直方图
def show_revolve_uniform_hist(self, img_array):
self.show_hist(img_array, [10], [0, 10])
# 显示图像
def show_image(self, image_array):
cv2.imshow('Image', image_array)
cv2.waitKey(0)
if __name__ == '__main__':
image = "2.jpg"
lbp = LBP()
image_array = lbp.describe(image)
# 获取图像原始LBP特征,并显示其统计直方图与特征图像
basic_array = lbp.lbp_basic(image_array)
basic_data = basic_array
print(basic_data)
—————————————————————————————————————————————————————————————————
—————————————————————————————————————————————————————————————————
Hu特征提取
自定义求矩函数,主要是根据公式将一个个参数求出
param img_gray: 灰度图像,对于二值图像来说就只有两个灰度0和255
return: 返回以10为底对数化后的hu不变矩
由于7个不变矩的变化范围很大,为了便于比较,可利用取对数的方法进行数据压缩;
同时考虑到不变矩有可能出现负值的情况,因此,在取对数之前先取绝对值
经修正后的不变矩特征具有平移 、旋转和比例不变性
import cv2
import numpy as np
def def_moments(img_gray):
# 标准矩定义为m_pq = sumsum(x^p * y^q * f(x, y))其中f(x,y)为像素点处的灰度值
row, col = img_gray.shape
# 计算图像的0阶几何矩
m00 = 0.0
##初始化一到三阶几何矩
# 计算一阶矩阵
m10 = m01 = 0.0
# 计算图像的二阶、三阶几何矩
m11 = m20 = m02 = m12 = m21 = m30 = m03 = 0.0
for i in range(row):
for j in range(col):
m00 += img_gray[i][j]
m10 += i * img_gray[i][j]
m20 += i ** 2 * img_gray[i][j]
m30 += i ** 3 * img_gray[i][j]
m11 += i * j * img_gray[i][j]
m12 += i * j ** 2 * img_gray[i][j]
m21 += i ** 2 * j * img_gray[i][j]
for j in range(col):
for i in range(row):
m01 += (j * img_gray[i, j])
m02 += (j ** 2 * img_gray[i, j])
m03 += (j ** 3 * img_gray[i, j])
# 由标准矩我们可以得到图像的"重心"
u10 = m10 / m00
u01 = m01 / m00
# 计算图像的二阶中心矩、三阶中心矩
y00 = y10 = y01 = y11 = y20 = y02 = y30 = y12 = y21 = y03 = 0.0
for x in range(row):
for y in range(col):
x_ = x - u10
y_ = y - u01
y00 += img_gray[x][y]
y10 += x_ * img_gray[x][y]
y01 += y_ * img_gray[x][y]
y11 += x_ * y_ * img_gray[x][y]
y02 += y_ ** 2 * img_gray[x][y]
y20 += x_ ** 2 * img_gray[x][y]
y03 += y_ ** 3 * img_gray[x][y]
y30 += x_ ** 3 * img_gray[x][y]
y12 += x_ * y_ ** 2 * img_gray[x][y]
y21 += x_ ** 2 * y_ * img_gray[x][y]
# 计算图像的归一化中心矩
n20 = y20 / (y00 ** 2)
n02 = y02 / (y00 ** 2)
n11 = y11 / (y00 ** 2)
n30 = y30 / (y00 ** 2.5)
n03 = y03 / (y00 ** 2.5)
n12 = y12 / (y00 ** 2.5)
n21 = y21 / (y00 ** 2.5)
# 计算图像的七个不变矩
h1 = n20 + n02
h2 = (n20 - n02) ** 2 + 4 * (n11 ** 2)
h3 = (n30 - 3 * n12) ** 2 + (3 * n21 - n03) ** 2
h4 = (n30 + n12) ** 2 + (n21 + n03) ** 2
h5 = (n30 - 3 * n12) * (n30 + n12) * ((n30 + n12) ** 2 - 3 * (n21 + n03) ** 2) + (3 * n21 - n03) * (n21 + n03) \
* (3 * (n30 + n12) ** 2 - (
n21 + n03) ** 2)
h6 = (n20 - n02) * ((n30 + n12) ** 2 - (n21 + n03) ** 2) + 4 * n11 * (n30 + n12) * (n21 + n03)
h7 = (3 * n21 - n03) * (n30 + n12) * ((n30 + n12) ** 2 - 3 * (n21 + n03) ** 2) + (3 * n12 - n30) * (n21 + n03) \
* (3 * (n30 + n12) ** 2 - (
n21 + n03) ** 2)
inv_m7 = [h1, h2, h3, h4, h5, h6, h7]
humoments = np.log(np.abs(inv_m7))
return humoments
if __name__ == '__main__':
img = cv2.imread("2.jpg")
img_gary = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
color_data = def_moments(img_gary)
print(color_data)
转自:https://blog.csdn.net/qq_45769063/article/details/107405546
网友评论