如何解决如何在OpenCV中将像素投影到特征向量上?
给出轮廓,我可以通过执行PCA来提取均值和特征向量。然后我想将所有像素投影到特征向量上的轮廓内。下面是我的代码和图片读取图像,提取轮廓并绘制第一个组件
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
src = cv.imread(cv.samples.findFile('/Users/bryan/Desktop/lung.png'))
gray = cv.cvtColor(src,cv.COLOR_BGR2GRAY)
def drawAxis(img,p_,q_,colour,scale):
p = list(p_)
q = list(q_)
## [visualization1]
angle = atan2(p[1] - q[1],p[0] - q[0]) # angle in radians
hypotenuse = sqrt((p[1] - q[1]) * (p[1] - q[1]) + (p[0] - q[0]) * (p[0] - q[0]))
# Here we lengthen the arrow by a factor of scale
q[0] = p[0] - scale * hypotenuse * cos(angle)
q[1] = p[1] - scale * hypotenuse * sin(angle)
cv.line(img,(int(p[0]),int(p[1])),(int(q[0]),int(q[1])),1,cv.LINE_AA)
# create the arrow hooks
p[0] = q[0] + 9 * cos(angle + pi / 4)
p[1] = q[1] + 9 * sin(angle + pi / 4)
cv.line(img,cv.LINE_AA)
p[0] = q[0] + 9 * cos(angle - pi / 4)
p[1] = q[1] + 9 * sin(angle - pi / 4)
cv.line(img,cv.LINE_AA)
def getOrientation(pts,img,scale_factor=25):
## [pca]
# Construct a buffer used by the pca analysis
sz = len(pts)
data_pts = np.empty((sz,2),dtype=np.float64)
for i in range(data_pts.shape[0]):
data_pts[i,0] = pts[i,0]
data_pts[i,1] = pts[i,1]
# Perform PCA analysis
mean = np.empty(0)
mean,eigenvectors,eigenvalues = cv.PCACompute2(data_pts,mean)
# Store the center of the object
cntr = (int(mean[0,0]),int(mean[0,1]))
## [pca]
## [visualization]
# Draw the principal components
cv.circle(img,cntr,3,(255,255),2)
p1 = (
cntr[0] + scale_factor * eigenvectors[0,0],cntr[1] + scale_factor * eigenvectors[0,1])
p2 = (
cntr[0] - scale_factor * eigenvectors[1,cntr[1] - scale_factor * eigenvectors[1,1])
drawAxis(img,p1,(0,255,0),4)
## [visualization]
# doing projections along eigenvectors
dim1_ = []
for _ in data_pts:
p = make_vector_projection(_,np.array(p1))
dim1_.append(p.astype(int))
dim1 = np.array(dim1_)
dim2_ = []
for _ in data_pts:
p = make_vector_projection(_,np.array(p2))
dim2_.append(p.astype(int))
dim2 = np.array(dim2_)
return mean,eigenvalues,p2,dim1,dim2
for i,c in enumerate(contours):
mean,evecs,evalues,dim2 = getOrientation(c,src)
plt.figure(figsize=(10,10))
plt.axis('equal')
plt.gca().invert_yaxis()
plt.imshow(src)
如我所料,但我想仔细检查一下,我计算了第一维随机矢量和第一个特征矢量之间的角度。我定义了
def unit_vector(vector):
""" Returns the unit vector of the vector. """
return vector / np.linalg.norm(vector)
def angle_between(v1,v2):
""" Returns the angle in radians between vectors 'v1' and 'v2'::
>>> angle_between((1,0))
1.5707963267948966
>>> angle_between((1,(1,0))
0.0
>>> angle_between((1,(-1,0))
3.141592653589793
"""
v1_u = unit_vector(v1)
v2_u = unit_vector(v2)
return np.arccos(np.clip(np.dot(v1_u,v2_u),-1.0,1.0))
for i,src)
draw_point = dim1[45].astype(int) # extract the first dimension
print(draw_point,evecs[0],angle_between(draw_point,p1))
print('#'* 10)
我得到如下输出,angle_between是弧度的,接近零意味着它们是平行的
[ 97 148] [ 0.14189901 -0.98988114] 0.002321780300502494
##########
[332 163] [-0.22199134 -0.97504864] 0.0006249775357550807
##########
我想在特征向量上绘制投影点时出现问题。我绘制的点不在绿线(我的特征向量)上。我的代码是
point_colors = [
(0,# blue
(0,0) # green
]
for i,src)
draw_point = dim1[45].astype(int)
print(draw_point,p1))
cv.circle(src,(draw_point[1],draw_point[0]),7,point_colors[i],2) # plot point
print('#'* 10)
我的问题是,我想在本征向量线上绘制所有投影像素,但是由于点不在本征向量线上,所以我的计算似乎不正确。你能帮忙吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。