'''
此標註工具功能比較單一:
鼠標左鍵進行標記
鼠標中間鍵進行轉換(標記狀態)
鼠標右鍵進行標記點刪除
'''
import os
import cv2
import copy as cp
import time
infilename = "/Users/v_cuiguang/test/in_file/data"
outfilename= "/Users/v_cuiguang/test/out_file/data"
def list_r_l(img_i):
with open(os.path.join(outfilename,imgname[img_i])+'.txt','r')as f:
# lr 左右list中哪一個
while True:
line = f.readline()
if line == '':
break
lr,x,y =line.split(' ')
if lr == 0:
list_l.append([int(y), int(x)])
else:
list_r.append([int(y), int(x)])
def deal(event, x, y, flags, param):
global flag_left, resim, resim_copy
# 如果存在標記文件,將先前的標記結果讀取出來,畫圖,並操作
for list_index in range(len(list_l)):
cv2.circle(resim, (list_l[list_index][1], list_l[list_index][0]), 2, (255, 0, 0), 1)
if len(list_l) > 1 and list_index < len(list_l) - 1:
resim = cv2.line(resim, (list_l[list_index][1], list_l[list_index][0]),
(list_l[list_index + 1][1], list_l[list_index + 1][0]), (0, 255, 0), 2)
for list_index in range(len(list_r)):
cv2.circle(resim, (list_r[list_index][1], list_r[list_index][0]), 2, (255, 0, 0), 1)
if len(list_r) > 1 and list_index < len(list_r) - 1:
resim = cv2.line(resim, (list_r[list_index][1], list_r[list_index][0]),
(list_r[list_index + 1][1], list_r[list_index + 1][0]), (0, 255, 0), 2)
# 按下鼠標左鍵
if event == cv2.EVENT_LBUTTONDOWN:
print('flag_left:',flag_left)
if flag_left or (len(list_l)==0 and len(list_r)==0):
print('鼠標左鍵點擊左側 mark left lane point')
resim = cv2.circle(resim,(x,y),2,(255,0,0),1)
list_l.append([y,x])
print('list_l',list_l)
index_l = len(list_l)
if index_l > 1:
resim = cv2.line(resim,(list_l[index_l-2][1],list_l[index_l-1][0]),(list_l[index_l-1][1],list_l[index_l-1][0]),(255,0,0),2)
if flag_left == False:
print("mark right lane point")
resim = cv2.circle(resim,(x,y),3,(255,0,255),3)
list_r.append([y,x])
print('list_r',list_r)
index_r = len(list_r)
if index_r > 1:
resim = cv2.line(resim, (list_r[index_r - 2][1], list_r[index_r - 1][0]),
(list_r[index_r - 1][1], list_r[index_r - 1][0]), (255, 0, 0), 2)
# 按下鼠標中間鍵
elif event == cv2.EVENT_MBUTTONDOWN:
flag_left = not flag_left
print("switch to mark right lane!")
# 按下鼠標右鍵
elif event == cv2.EVENT_RBUTTONDOWN:
resim = cp.deepcopy(resim_copy)
# 刪除list_l中的標記點
print(list_l)
print(list_r)
if (flag_left == True and len(list_l) > 0):
print('flag_left',flag_left)
print('list_l:', list_l)
print("drop left lane point")
list_l.pop()
if (len(list_r)== 0 and flag_left == False):
print('flag_left', flag_left)
print('list_r:', list_r)
print("drop left lane point")
list_l.pop()
flag_left = True
# 刪除list_r中的標記點
if flag_left == False:
print("drop right lane point")
list_r.pop()
def mkdir(path):
path = path.strip()
path = path.rstrip("\\")
isExists = os.path.exists(path)
if not isExists:
os.makedirs(path)
return True
else:
return False
if __name__ == "__main__":
imgname = []
# list.text 文件使用圖片的相對路徑
with open(infilename+'/list.txt','r')as f:
while True:
line = f.readline()
print(line)
line = line.strip('\n')
if not line:
break
imgname.append(line)
list_l = []
list_r = []
flag_left = True
img_i = 0
# 判斷輸出路徑是否存在,如果不存在就創建次路徑
mkdir(outfilename)
list_r_l(img_i)
# 創建窗口
cv2.namedWindow('dealLane',cv2.WINDOW_NORMAL)
# 鼠標觸發時間回調函數
cv2.setMouseCallback('dealLane',deal)
global resim, resim_copy
# 讀取一張彩色圖片
resim = cv2.imread(infilename+"/"+imgname[img_i], 1)
if resim is None:
print('圖片不存在!')
print('read image:'+ infilename+'/'+imgname[img_i])
resim_copy = cp.deepcopy(resim)
while True:
cv2.imshow('dealLane', resim)
# 在窗口操作
if cv2.waitKey(10) & 0xFF == 9: # TAB鍵
#清空list_l/list_r列表,爲下一次存儲做準備
# 字符串拼接路徑
# 如果在窗口中按下tab鍵,則現將圖片上標記的的點保存,然後清空list_r/list_l列表 ,圖片索引下標+1
# 注意此處寫入如果是追加效果,點數過多會佔用太多的cpu
print('11111',os.path.exists(outfilename + '/' + 'abv.jpg' + '.txt'))
print('imgname[img_i]',imgname[img_i])
with open(outfilename + '/' + imgname[img_i] + '.txt', 'w') as f:
print('22222', os.path.exists(outfilename + '/' + 'abv.jpg' + '.txt'))
for list_index in range(len(list_l)):
f.write("0 " + str(list_l[list_index][1]) + " " + str(list_l[list_index][0]) + "\n")
for list_index in range(len(list_r)):
f.write("1 " + str(list_r[list_index][1]) + " " + str(list_r[list_index][0]) + "\n")
print("finish save lane point file!")
flag_left = True
flag_right = False
del list_l[:]
del list_r[:]
# 圖片;路徑列表+1
img_i = img_i + 1
# 讀取原來輸出文件中的信息存放在list_r 或 list_l中
if os.path.exists(outfilename + '/' + imgname[img_i] + '.txt'):
list_r_l(img_i)
resim = cv2.imread(str(infilename)+"/"+imgname[img_i], 1)
if resim is None:
print("圖片不存在!")
break
print("read image"+ infilename+"/"+imgname[img_i])
resim_copy = cp.deepcopy(resim)
elif cv2.waitKey(10) & 0xFF == 27:
print(cv2.waitKey(10) & 0xFF)
cv2.destroyAllWindows()
exit()
elif cv2.waitKey(10) & 0xFF == 115 or cv2.waitKey(10) & 0xFF == 83:
print(cv2.waitKey(10) & 0xFF)
with open(outfilename + '/' + imgname[img_i] + '.txt', 'a') as f:
for list_index in range(len(list_l)):
f.write("0 " + str(list_l[list_index][1]) + " " + str(list_l[list_index][0]) + "\n")
for list_index in range(len(list_r)):
f.write("1 " + str(list_r[list_index][1]) + " " + str(list_r[list_index][0]) + "\n")
print("finish save lane point file!")
# time.sleep(1)
# 釋放所有窗口
cv2.destroyAllWindows()
完成結果展示:
初學希望能和大家多多交流!
參考博客原地址:https://blog.csdn.net/csuzhaoqinghui/article/details/84797378