计算blob 方向有两种方法:一种是利用PCA;一种是利用图像矩。
本次主要介绍基于PCA算法的计算:
1、 点矩阵
我们将处理的二维点大小为2*m,第一行为x,第二行为y
2、 每个点减去均值
计算x坐标的行数。对于每个x点,减去它的均值。对y坐标做同样的处理。平均减法最小化了近似数据和中心数据的均方误差。
3、 计算协方差 2*2
4、 特征值与特征向量计算
5、 特征向量重排序,特征值大的对应的特征向量是方差最大的方向】
6、 绘制主成分
7、 计算旋转角度—长轴与水平方向的角
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
from scipy.misc.pilutil import imread
#import skimage.filter
img = imread(r'C:\Users\Y\Desktop\blob_axes-skewed_oval.png', flatten=1)
#img=255-img
y, x = np.nonzero(img)
x = x - np.mean(x)
y = y - np.mean(y)
coords = np.vstack([x, y])
cov = np.cov(coords)
evals, evecs = np.linalg.eig(cov)
sort_indices = np.argsort(evals)[::-1]
x_v1, y_v1 = evecs[:, sort_indices[0]] # Eigenvector with largest eigenvalue
x_v2, y_v2 = evecs[:, sort_indices[1]]
scale = 20
x1=np.linspace(-10,10,30)
y1=x1*y_v1/x_v1
#plt.plot([x_v1*-scale, x_v1*scale],
# [y_v1*-scale, y_v1*scale], color='red')
plt.plot(x1,y1,'r-')
#plt.plot([x_v2*-scale, x_v2*scale],
# [y_v2*-scale, y_v2*scale], color='blue')
x2=np.linspace(-10,10,30)
y2=x2*y_v2/x_v2
plt.plot(x2,y2,'b-')
theta = np.arccos(y_v1/np.sqrt(x_v1**2+y_v1**2)) #与水平方向的夹角
#theta=np.arctan(y_v1/x_v1)+np.pi*2
rotation_mat = np.matrix([[np.cos(theta), -np.sin(theta)],
[np.sin(theta), np.cos(theta)]])
transformed_mat = rotation_mat * coords
# plot the transformed blob
x_transformed, y_transformed = transformed_mat.A
plt.plot(x_transformed, y_transformed, 'g.')
plt.plot(x, y, 'k.')
plt.axis('equal')
plt.gca().invert_yaxis() # Match the image system with origin at top left
plt.show()