配準常見的評判標準就是關鍵點座標之間的誤差(TRE),關鍵點的標註就成了繞不開的過程。有很多圖像處理軟件都可以實現在圖像上畫點並且顯示鼠標處的座標,如windows自帶的繪圖軟件,ImageJ等,但是我當下的任務需求是標記圖像對上對應的關鍵點,並生成相應的txt文本。稍微調查了一下各種標記軟件,未果,最終決定自己寫代碼實現。
關鍵函數
這個函數可以用來捕獲鼠標點擊處的座標,函數返回一個列表,保存着每次點擊的座標。具體的函數說明看下圖或者點擊上面的超鏈接查看。注意這個函數有一個timeout的限制,而且很坑的是這個timeout默認的是30而不是永久。
opencv繪圖的函數,用來畫關鍵點。給點的中心位置和半徑,在圖像上畫圈圈,返回畫完的圖像。詳見下圖。
同樣是opencv的繪圖函數。用來顯示標記的點的順序,方便標記對應的圖像。
代碼
思路:顯示圖片,標記點,顯示標記後的圖像,顯示另一張圖像,標記點,顯示標記後的圖像,關閉圖像,保存爲文本文件。
'''
關鍵點標註代碼
輸入:一對圖像的索引
輸出:一個txt文件,保存着3對點的座標
'''
import matplotlib.pyplot as plt
import numpy as np
import cv2
import sys
#參數
index =int(sys.argv[1])
IMAGE1 = "fix_test/%d.JPG"%index#固定圖像路徑
IMAGE2 = "move_test/%d.JPG"%index#浮動圖像路徑
filename = 'label_test/%d.txt'%index#保存的文件路徑
NUM_P = 10 #點的數量
point_size = 20 #點的尺寸
color = (255, 255, 255) # 點和文字的顏色,全白
point_thickness = -1 # 點的圈圈的粗細
text_thickness=3
text_size=3#文字尺寸
img1 = cv2.imread(IMAGE1)
b,g,r = cv2.split(img1)
img1 = cv2.merge([r,g,b])
img2 = cv2.imread(IMAGE2)
b,g,r = cv2.split(img2)
img2 = cv2.merge([r,g,b])
#標註圖像
plt.subplot(121)
plt.imshow(img1)
pos1=plt.ginput(n=NUM_P,timeout=0)
print(pos1)
for i in range(NUM_P):
x,y = pos1[i]
x = int(x)
y = int(y)
point = (x,y)
cv2.circle(img1, point, point_size, color, point_thickness)
cv2.putText(img1,"%d"%(i+1),point,cv2.FONT_HERSHEY_SIMPLEX,text_size,color,text_thickness)
plt.imshow(img1)
plt.subplot(122)
plt.imshow(img2)
pos2=plt.ginput(n=NUM_P,timeout=0)
for i in range(NUM_P):
x,y = pos2[i]
x = int(x)
y = int(y)
point = (x,y)
cv2.circle(img2, point, point_size, color, point_thickness)
cv2.putText(img2,"%d"%(i+1),point,cv2.FONT_HERSHEY_SIMPLEX,text_size,color,text_thickness)
print(pos2)
plt.imshow(img2)
plt.show()
#寫入文件
with open(filename, 'w') as f:
for i in range(3):
x1,y1 = pos1[i]
x1 = int(x1)
y1 = int(y1)
x2,y2 = pos2[i]
x2 = int(x2)
y2 = int(y2)
f.write("%d %d %d %d\n"%(x1,y1,x2,y2))
效果
生成的text 文件
參考資料