一、LBP局部二值模式
将每个像素点和周围点比较,大小量化为0和1,多个bit组成一个数,统计数的直方图
优点在于灰度不变性和旋转不变性
以下图为例:
LBP部分特征:
[3.24522569e-02 1.70852623e-02 6.80941358e-04 4.17004244e-03
1.46527778e-02 2.72762346e-03 4.03356481e-03 2.13522377e-02
7.57137346e-04 3.76639660e-04 3.80979938e-05 1.18634259e-04
4.26601080e-03 1.10918210e-03 6.38406636e-03 1.88956404e-02
1.75718557e-02 7.30516975e-03 3.51562500e-04 1.15113812e-03
2.53906250e-03 3.20698302e-04 9.59683642e-04 2.39679784e-03
4.29301698e-03 1.15933642e-03 1.42264660e-04 4.10397377e-04
2.17158565e-02 2.52170139e-03 1.99426119e-02 3.43262924e-02
7.19521605e-04 4.03163580e-04 3.08641975e-05 1.15258488e-04
3.06712963e-04 5.78703704e-05 1.08024691e-04 4.36921296e-04
4.34027778e-05 1.92901235e-05 2.41126543e-06 1.10918210e-05
1.35995370e-04 4.14737654e-05 1.32619599e-04 4.04610340e-04
4.45746528e-03 1.23312114e-03 1.03684414e-04 3.60243056e-04
8.57928241e-04 9.01813272e-05 3.80497685e-04 8.54070216e-04
7.13493441e-03 8.72878086e-04 1.23939043e-04 3.67476852e-04
1.82253086e-02 8.57928241e-04 8.20071373e-03 9.73861883e-03
1.47299383e-02 2.59355710e-03 2.94656636e-04 8.55516975e-04
6.14390432e-03 2.87422840e-04 1.02285880e-03 2.20244985e-03
3.14911265e-04 5.30478395e-05 1.78433642e-05 2.70061728e-05
1.03153935e-03 1.08506944e-04 8.72395833e-04 8.56481481e-04
2.79417438e-03 3.30825617e-04 5.54591049e-05 9.64506173e-05
3.57831790e-04 1.92901235e-05 1.16222994e-04 8.48765432e-05
9.46662809e-04 1.03684414e-04 2.55594136e-05 5.93171296e-05
2.25549769e-03 9.16280864e-05 8.72395833e-04 9.13387346e-04
4.35040509e-03 1.05565201e-03 1.16705247e-04 3.89178241e-04
1.06770833e-03 1.01273148e-04 3.22627315e-04 8.75289352e-04
1.21045525e-04 3.95447531e-05 5.78703704e-06 1.01273148e-05
4.79359568e-04 9.54861111e-05 4.20042438e-04 6.65027006e-04
2.30179398e-02 2.66396605e-03 4.64409722e-04 8.36709105e-04
2.28780864e-03 7.33024691e-05 8.98437500e-04 1.30160108e-03
1.97559799e-02 8.61786265e-04 3.23109568e-04 5.62307099e-04
3.60947145e-02 9.99228395e-04 1.12500000e-02 1.09143519e-02
7.73533951e-04 4.70389660e-03 4.72608025e-05 7.90557485e-03
3.16840278e-04 9.65952932e-04 1.30208333e-04 2.10831404e-02
1.63966049e-05 1.18152006e-04 9.64506173e-07 1.05131173e-04
1.32619599e-04 4.22453704e-04 1.29243827e-04 8.71141975e-03
4.09915123e-04 1.18393133e-03 2.07368827e-05 8.76253858e-04
5.30478395e-05 9.35570988e-05 2.65239198e-05 8.86863426e-04
1.19116512e-04 3.46739969e-04 6.75154321e-06 3.36130401e-04
4.14737654e-04 8.22723765e-04 3.66994599e-04 9.44974923e-03
4.62962963e-05 1.47569444e-04 2.41126543e-06 1.32619599e-04
1.63966049e-05 3.27932099e-05 3.85802469e-06 3.43846451e-04
3.85802469e-06 6.26929012e-06 0.00000000e+00 7.71604938e-06
5.30478395e-06 1.68788580e-05 1.20563272e-05 3.44328704e-04
1.54803241e-04 4.54764660e-04 1.20563272e-05 3.72781636e-04
2.94174383e-05 7.28202160e-05 1.20563272e-05 5.44463735e-04
1.10435957e-04 3.53009259e-04 1.39853395e-05 7.16145833e-04
2.89834105e-04 5.36747685e-04 2.90798611e-04 8.04060571e-03
4.69232253e-03 2.21537423e-02 1.43229167e-04 1.95693480e-02
1.06336806e-03 2.27575231e-03 5.15046296e-04 3.69724151e-02
1.25385802e-04 4.35956790e-04 3.85802469e-06 2.94174383e-04
3.57349537e-04 8.44425154e-04 4.50906636e-04 1.07908951e-02
1.16271219e-03 2.48167438e-03 3.76157407e-05 8.74324846e-04
1.09953704e-04 8.96990741e-05 8.82523148e-05 1.05372299e-03
3.88695988e-04 8.05844907e-04 1.63966049e-05 4.93827160e-04
8.72878086e-04 1.34934414e-03 6.57793210e-04 1.04287230e-02
7.19135802e-03 2.10180363e-02 1.21527778e-04 9.09915123e-03
9.78973765e-04 9.72704475e-04 4.35956790e-04 1.13165509e-02
1.33584105e-04 3.52527006e-04 1.06095679e-05 2.87905093e-04
4.93827160e-04 6.95891204e-04 7.84625772e-04 1.02541474e-02
2.09558256e-02 3.55189043e-02 4.12808642e-04 1.04036458e-02
9.56790123e-04 9.49556327e-04 6.94926698e-04 1.10474537e-02
9.52594522e-03 1.01572145e-02 3.46739969e-04 8.41242284e-03
1.13049769e-02 1.09432870e-02 1.07889660e-02 1.31738040e-01]
代码:
import cv2 as cv
from skimage import feature as skif
import numpy as np
#获取图像的lbp特征
def get_lbp_data(image_path, lbp_radius=1, lbp_point=8):
# img = utils.change_image_rgb(image_path)
img = cv.imread(image_path)
image = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 使用LBP方法提取图像的纹理特征.
#lbp_point:选取中心像素周围的像素点的个数;lbp_radius:选取的区域的半径
#以下为5种不同的方法提取的lbp特征,相应的提取到的特征维度也不一样
#'default': original local binary pattern which is gray scale but notrotation invariant
#'ror': extension of default implementation which is gray scale androtation invariant
#'uniform': improved rotation invariance with uniform patterns andfiner quantization of the angular space which is gray scale and rotation invariant.
#'nri_uniform': non rotation-invariant uniform patterns variantwhich is only gray scale invariant
#'var': rotation invariant variance measures of the contrast of localimage texture which is rotation but not gray scale invariant
lbp = skif.local_binary_pattern(image, lbp_point, lbp_radius, 'default')
# 统计图像的直方图
max_bins = int(lbp.max() + 1)
#print(max_bins)
# hist size:256
hist, _ = np.histogram(lbp, density=True, bins=max_bins, range=(0, max_bins))
return hist
image_path = 'toy.jpg' #读取图片
feature = get_lbp_data(image_path) #调用函数
print(feature)
代码:
clear all;
clc;
img=imread('toy.jpg');
img=rgb2gray(img);
[m,n]=size(img);
imgn=zeros(m,n);
for i=2:m-1
for j=2:n-1
for p=i-1:i+1
for q =j-1:j+1
if img(p,q) > img(i,j)||img(p,q) ==img(i,j)
if p~=i || q~=j
if(p==i&&q==j-1)
imgn(i,j)=imgn(i,j)+2^0;
end
if(p==i+1&&q==j-1)
imgn(i,j)=imgn(i,j)+2^1;
end
if(p==i+1&&q==j)
imgn(i,j)=imgn(i,j)+2^2;
end
if(p==i+1&&q==j+1)
imgn(i,j)=imgn(i,j)+2^3;
end
if(p==i&&q==j+1)
imgn(i,j)=imgn(i,j)+2^4;
end
if(p==i-1&&q==j+1)
imgn(i,j)=imgn(i,j)+2^5;
end
if(p==i-1&&q==j)
imgn(i,j)=imgn(i,j)+2^6;
end
if(p==i-1&&q==j-1)
imgn(i,j)=imgn(i,j)+2^7;
end
end
end
end
end
end
end
figure;subplot(1,2,1),imshow(img),title('原图');
subplot(1,2,2),imshow(imgn,[]),title('LBP');
旋转不变LBP:
代码;
img=imread('toy.jpg');
img=rgb2gray(img);
t=5;
img=double(img);
[m n]=size(img);
imgn_upper=zeros(m,n);%初始化结果矩阵(正值)
imgn_lower=zeros(m,n);%初始化结果矩阵(负值)
for i=2:m-1
for j=2:n-1
for p=i-1:i+1%遍历周边像素
for q =j-1:j+1
if p~=i || q~=j %不取目标像素
%%%正值提取结果
if (img(p,q) - img(i,j))>t||(img(p,q) - img(i,j))==t
if(p==i&&q==j-1)
imgn_upper(i,j)=imgn_upper(i,j)+2^0;
end
if(p==i+1&&q==j-1)
imgn_upper(i,j)=imgn_upper(i,j)+2^1;
end
if(p==i+1&&q==j)
imgn_upper(i,j)=imgn_upper(i,j)+2^2;
end
if(p==i+1&&q==j+1)
imgn_upper(i,j)=imgn_upper(i,j)+2^3;
end
if(p==i&&q==j+1)
imgn_upper(i,j)=imgn_upper(i,j)+2^4;
end
if(p==i-1&&q==j+1)
imgn_upper(i,j)=imgn_upper(i,j)+2^5;
end
if(p==i-1&&q==j)
imgn_upper(i,j)=imgn_upper(i,j)+2^6;
end
if(p==i-1&&q==j-1)
imgn_upper(i,j)=imgn_upper(i,j)+2^7;
end
%%%负值提取结果
elseif (img(p,q) - img(i,j))<-t||(img(p,q) - img(i,j))==-t
if(p==i&&q==j-1)
imgn_lower(i,j)=imgn_lower(i,j)+2^0;
end
if(p==i+1&&q==j-1)
imgn_lower(i,j)=imgn_lower(i,j)+2^1;
end
if(p==i+1&&q==j)
imgn_lower(i,j)=imgn_lower(i,j)+2^2;
end
if(p==i+1&&q==j+1)
imgn_lower(i,j)=imgn_lower(i,j)+2^3;
end
if(p==i&&q==j+1)
imgn_lower(i,j)=imgn_lower(i,j)+2^4;
end
if(p==i-1&&q==j+1)
imgn_lower(i,j)=imgn_lower(i,j)+2^5;
end
if(p==i-1&&q==j)
imgn_lower(i,j)=imgn_lower(i,j)+2^6;
end
if(p==i-1&&q==j-1)
imgn_lower(i,j)=imgn_lower(i,j)+2^7;
end
end
end
end
end
end
end
subplot(1,2,1),imshow(imgn_upper,[]),title('LTP正值提取');
subplot(1,2,2),imshow(imgn_lower,[]),title('LTP负值提取');
二、GABOR
用于边缘提取的线性滤波器,适合纹理分析,能提供良好的方向选择与尺度选择,对光照变化不敏感,是三角函数的叠加
以下图为例:
Gabor处理后:
代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt
# Grayscale
def BGR2GRAY(img):
# Grayscale
gray = 0.2126 * img[..., 2] + 0.7152 * img[..., 1] + 0.0722 * img[..., 0]
return gray
# Gabor Filter
def Gabor_filter(K_size=111, Sigma=10, Gamma=1.2, Lambda=10, Psi=0, angle=0):
# get half size
d = K_size // 2
# prepare kernel
gabor = np.zeros((K_size, K_size), dtype=np.float32)
# each value
for y in range(K_size):
for x in range(K_size):
# distance from center
px = x - d
py = y - d
# degree -> radian
theta = angle / 180. * np.pi
# get kernel x
_x = np.cos(theta) * px + np.sin(theta) * py
# get kernel y
_y = -np.sin(theta) * px + np.cos(theta) * py
# fill kernel
gabor[y, x] = np.exp(-(_x**2 + Gamma**2 * _y**2) / (2 * Sigma**2)) * np.cos(2*np.pi*_x/Lambda + Psi)
# kernel normalization
gabor /= np.sum(np.abs(gabor))
return gabor
# 使用Gabor滤波器作用于图像上
def Gabor_filtering(gray, K_size=111, Sigma=10, Gamma=1.2, Lambda=10, Psi=0, angle=0):
# get shape
H, W = gray.shape
# padding
gray = np.pad(gray, (K_size//2, K_size//2), 'edge')
# prepare out image
out = np.zeros((H, W), dtype=np.float32)
# get gabor filter
gabor = Gabor_filter(K_size=K_size, Sigma=Sigma, Gamma=Gamma, Lambda=Lambda, Psi=0, angle=angle)
# filtering
for y in range(H):
for x in range(W):
out[y, x] = np.sum(gray[y : y + K_size, x : x + K_size] * gabor)
out = np.clip(out, 0, 255)
out = out.astype(np.uint8)
return out
# 使用6个不同角度的Gabor滤波器对图像进行特征提取
def Gabor_process(img):
# get shape
H, W, _ = img.shape
# gray scale
gray = BGR2GRAY(img).astype(np.float32)
# define angle
#As = [0, 45, 90, 135]
As = [0,30,60,90,120,150]
# prepare pyplot
plt.subplots_adjust(left=0, right=1, top=1, bottom=0, hspace=0, wspace=0.2)
out = np.zeros([H, W], dtype=np.float32)
# each angle
for i, A in enumerate(As):
# gabor filtering
_out = Gabor_filtering(gray, K_size=11, Sigma=1.5, Gamma=1.2, Lambda=3, angle=A)
# add gabor filtered image
out += _out
# scale normalization
out = out / out.max() * 255
out = out.astype(np.uint8)
return out
# Read image
img = cv2.imread("toy.jpg").astype(np.float32)
# gabor process
out = Gabor_process(img)
cv2.imwrite("out.jpg", out)
cv2.imshow("result", out)
cv2.waitKey(0)
cv2.destroyAllWindows()