'''
此标注工具功能比较单一:
鼠标左键进行标记
鼠标中间键进行转换(标记状态)
鼠标右键进行标记点删除
'''
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