我从激光扫描的一组点开始,我使用matplotlib将其绘制为散点图。然后,我使用plt.savefig将图作为图像打开,并使用openCV在点周围找到轮廓。现在,我希望能够找到轮廓的中心并将其绘制为原始散点图中的点。问题是我不知道如何在原始散点图点和图像像素之间创建映射。有没有办法做到这一点?还是在matplotlib中标记轮廓中心的另一种方法?
注意:之所以需要绘制轮廓,是因为以后我需要使用openCV的matchShapes函数比较轮廓。
以下是每个步骤的图像:
散点图
,
轮廓以红色标记的中心
现在,我基本上希望能够将图像中的红色标记添加到散点图中。
这是我的代码:
plt.scatter(X[:,0], X[:,1], s=2)
plt.axis('equal')
plt.axis('off')
plt.savefig(name)
plt.clf()
img = cv2.imread(name)
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgGray, 127, 255, 0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
height = img.shape[0]
width = img.shape[1]
blank_image = np.zeros((height,width,3), np.uint8)
cv2.drawContours(blank_image, contours, -1, (255,0,0))
for contour in contours:
M = cv2.moments(contour)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
cv2.circle(blank_image, (cX, cY), 2, (0, 0, 255), -1)
cv2.imwrite(name, blank_image)
更新: 根据建议,我查看了matplot的transforms函数并尝试了以下操作:
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x_coords, y_coords, 'bo', markersize=2)
ax.axis('equal')
ax.axis('off')
height1 = fig.get_figheight()*fig.dpi
width1 = fig.get_figwidth()*fig.dpi
inv = ax.transData.inverted()
plt.savefig('img.png')
img = cv2.imread('img.png')
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgGray, 127, 255, 0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
height = img.shape[0]
width = img.shape[1]
blank_image = np.zeros((height,width,3), np.uint8)
centers_x = []
centers_y = []
for contour in contours:
M = cv2.moments(contour)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
centers_x.append(inv.transform((cX, height1-cY))[0])
centers_y.append(inv.transform((cX, height1-cY))[1])
cv2.drawContours(blank_image, [contour], -1, (255,0,0),1)
cv2.circle(blank_image, (cX, cY), 2, (0, 0, 255), -1)
cv2.imwrite("test.png", blank_image)
ax.plot(centers_x, centers_y, 'ro', markersize=4)
plt.show()
这使我靠近,但x坐标似乎仍然略有偏离
新结果]
。
我也尝试过
centers_x.append(inv.transform((width1-cX, height1-cY))[0])
centers_y.append(inv.transform((width1-cX, height1-cY))[1])
但是那也不起作用。
最终更新:添加
plt.tight_layout()
解决了问题。
答案 0 :(得分:0)
x = np.linspace(0,1,10)
y = 5*x+2
fig, ax = plt.subplots()
ax.scatter(x,y)
height = fig.get_figheight()*fig.dpi
width = fig.get_figwidth()*fig.dpi
# the coordinates in pixel
cX = 147
cY = 142
# we need to invert the y value as matplotlib considers (0,0) to be
# on the lower left, while opencv uses upper left as origin
tX,tY = ax.transData.inverted().transform([cX,height-cY])
ax.scatter(tX,tY, s=50, c='r')
fig.savefig('test.png', dpi=fig.dpi)