图像的特征提取

特征提取的方法主要是通过属性间的关系,如组合不同的属性得到新的属性,这样就改变了原来的特征空间。特征提取的结果是把图像上的点分为不同的子集,这些子集往往属于孤立的点、连续的曲线或者连续的区域。特征的好坏对泛化性能有至关重要的影响。

1. 特征降维:主成分分析法(PCA)

PCA所做的就是旋转所有的数据点直到它们分布到可以解释大部分数据分布的两个坐标系中。

接下来通过一个例子,感受主成分分析法的作用:

In [ ]:

%matplotlib inline

import numpy as np

import matplotlib.pyplot as plt

import cv2

首先创建一个散点图,模拟原始图像的分布:

In [ ]:

#均值

mean = [20, 20]

#协方差矩阵

cov = [[5 ,0], [25, 25]]

x, y = np.random.multivariate_normal(mean,cov,1000).T

# 输出原始图像

plt.plot(x,y,'o',zorder=1)

plt.xlabel('feature1')

plt.ylabel('feature2')

plt.show()

下面将特征向量x和y组成一个特征矩阵X:

In [ ]:

#把特征向量x和y组合成一个特征矩阵X

X= np.vstack((x,y)).T

#在特征X上计算PCA,指定一个空的np.array([])数组用作蒙版参数,告诉opencv使用特征矩阵上的所有数据点。

mu,eig= cv2.PCACompute(X, np.array([]))

print(eig)

返回两个值:投影前减去的平均值,和协方差矩阵的特征向量(eig)
这些特征向量指向PCA认为最有信息性的方向。

In [ ]:

# 画出上面得出的特征向量

plt.plot(x, y, 'o', zorder=1)

plt.quiver(mean[0], mean[1], eig[:, 0], eig[:, 1], zorder=3, scale=0.2, units='xy')

plt.text(mean[0] + 5 * eig[0, 0], mean[1] + 5 * eig[0, 1], 'u1', zorder=5,

         fontsize=16, bbox=dict(facecolor='white', alpha=0.6))

plt.text(mean[0] + 7 * eig[1, 0], mean[1] + 4 * eig[1, 1], 'u2', zorder=5,

         fontsize=16, bbox=dict(facecolor='white', alpha=0.6))

plt.axis([0, 40, 0, 40])

plt.xlabel('feature 1')

plt.ylabel('feature 2')

plt.show()

用PCA进行压缩阵列,旋转数据将最大分布方向的两个坐标轴与xy轴对齐:

In [ ]:

X2= cv2.PCAProject(X,mu,eig)

plt.plot(X2[:, 0], X2[:, 1], 'o')

plt.xlabel('first principal component')

plt.ylabel('second principal component')

plt.axis([-20, 20, -10, 10])

plt.show()

还可以基于sklearn实现独立的主成分分析:

In [ ]:

from sklearn import decomposition

ica= decomposition.FastICA()

X3= ica.fit_transform(X)

plt.plot(X3[:, 0], X3[:, 1], 'o')

plt.xlabel('first independent component')

plt.ylabel('second independent component')

plt.axis([-0.2, 0.2, -0.2, 0.2])

plt.show()

基于sklearn实现非负矩阵分解:

In [ ]:

nmf = decomposition.NMF()

X4 = nmf.fit_transform(X)

plt.plot(X4[:, 0], X4[:, 1], 'o')

plt.xlabel('first non-negative component')

plt.ylabel('second non-negative component')

plt.axis([-5, 15, -5, 15])

plt.show()

2. 局部二值模式LBP

BP的基本思想是以图像中某个像素为中心,对相邻像素进行阈值比较。如果中心像素的亮度大于等于它的相邻像素,把相邻像素标记为1,否则标记为0。我们可以用二进制数字来表示LBP图中的每个像素的LBP编码,比如下图中的中心像素,它的LBP编码为:00010011,其十进制值为19。

下面例子展示了LBP的基本用法:

In [ ]:

%matplotlib inline

from skimage.transform import rotate

from skimage.feature import local_binary_pattern

from skimage import data, io,data_dir,filters, feature

from skimage.color import label2rgb

import skimage

import numpy as np

import matplotlib.pyplot as plt

from PIL import Image

import cv2

设定LBP参数并读取图像,本节依然选用经典的lena.jpg

In [ ]:

# settings for LBP

radius = 1  # LBP算法中范围半径的取值

n_points = 8 * radius # 领域像素点数

# 读取图像

image = cv2.imread('./lena.jpg')

#显示到plt中,需要从BGR转化到RGB,若是cv2.imshow(win_name, image),则不需要转化

image1 = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

plt.imshow(image1)

plt.show()

转为灰度图像:

In [ ]:

image = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)

plt.imshow(image, plt.cm.gray)

plt.show()

进行LBP处理,得到纹理特征图像:

In [ ]:

lbp = local_binary_pattern(image, n_points, radius)

plt.imshow(lbp, plt.cm.gray)

plt.show()

进行Sobel处理,得到边缘特征图像:

In [ ]:

edges = filters.sobel(image)

plt.subplot(111)

plt.imshow(edges, plt.cm.gray)

plt.show()

  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值