计算用于方向确定的图像对象的中心点

问题描述 投票:0回答:1

我想在Python中看到哪些方向箭头指向图片。在下面的算法中,我计算了箭头的重心:

image = cv2.imread(image.tiff")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
thresh = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY)[1]

cnts = cv2.findContours(thresh.copy(), cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]

for c in cnts:
    M = cv2.moments(c)
    cX = int(M["m10"] / M["m00"])   # center of gravity (x coordinate)
    cY = int(M["m01"] / M["m00"])   # center of gravity (y coordinate)

enter image description here(红点是重心)

是否有另一种方法来确定箭头的中心点,以便中心点和重心之间的差异可用于计算箭头指向的方向?

python opencv direction opencv-contour
1个回答
1
投票

在这里,我的答案更详细...希望评论足够清楚!

import matplotlib.pyplot as plt
import imageio
import os
import numpy as np

# Load the image with imageio...
base_path = r'D:\temp'
im_name = 'arrow_image.png'
im_dir = os.path.join(base_path, im_name)
A = imageio.imread(im_dir)

# Get all the points that have a value in the A[:,:,0]-dimension of the image
pts2 = np.array([[j,i] for i in range(A.shape[0]) for j in range(A.shape[1]) if A[i,j,0] > 0])
# Using convexhull.. get an overlay of vertices for these found points
ch = ConvexHull(pts2)

# If you want to visualize them.. you can do that by
plt.plot(pts2[:, 0], pts2[:, 1], 'ko', markersize=10)
plt.show()

# Be aware that in this whole process your image might look like it has rotated.. so be aware of the dimension (and the way stuff is visualized)

# Get the indices of the hull points.
hull_indices = ch.vertices

# These are the actual points.
hull_pts = pts2[hull_indices, :]

# With this you are able to determine the 'end' points of your arrow. Fiddle around with it, know what you are trying to get and understand it.
z = [np.linalg.norm(x) for x in pts2]
z_max_norm = np.where(z==max(z))
z_min_norm = np.where(z==min(z))
y_max = np.where(pts2[:,1] == min(pts2[:,1]))[0]
x_min = np.where(pts2[:,0] == min(pts2[:,0]))[0]

# And here some more visualization tricks
plt.fill(hull_pts[:,0], hull_pts[:,1], fill=False, edgecolor='b')
# plt.scatter(pts2[z_min,0],pts2[z_min, 1])
# plt.scatter(pts2[z_max,0],pts2[z_max, 1])
plt.scatter(pts2[y_max,0],pts2[y_max, 1])
plt.scatter(pts2[x_min,0],pts2[x_min, 1])

plt.show()

这使用了与@GPPK答案相同的策略。我的另一个解决方案是将数据转换为1d ...你可以想到像这样的转换

pts3 = np.array([A[i,j,0]*i*np.log(j) for i in range(A.shape[0]) for j in range(A.shape[1]) if A[i,j,0] > 0])
plt.plot(pts3)
plt.show()

但你必须稍微测试一下,也许改变一些参数。这个想法是你折扣某些尺寸,以恢复箭头的形状。

© www.soinside.com 2019 - 2024. All rights reserved.