MakeLabel是一款用Python编写的,用于给图片区域内容作标注的工具软件。它的目的是给YOLOV5样本图片作标注,并生成可供YOLOV5训练使用的标签文件。
标签类别文件,声明训练所要标注的类别。一行一个类别,第1个是类别名称,第2个是序号。中间用英文逗号分隔。
人,0 猫,1 狗,2
主程序,程序很简单,所以没有做标注。主要是用Tkinter和PIL来实现。要和label.txt放在同一个目录内。
import tkinter as tk from tkinter import ttk import sys,os #import win32api,win32con from tkinter import filedialog from PIL import Image,ImageTk import tkinter.font #======================================================= def get_img(nid): global Values c = 0 for key,value in Values["Img_File"].items(): if(nid == c): return key c+=1 return "" #======================================================= def show_img(): global Values,bottom_Canvas,colors if(Values["Img_Dir"]=="" or Values["Label_Dir"]==""): Values["nID"] = 0 return nid = Values["nID"] if(nid >= len(Values["Img_File"])): nid = len(Values["Img_File"])-1 if(nid<0): nid = 0 Values["nID"] = nid fn = get_img(nid) if(fn==""): return fname = Values["Img_Dir"]+"\\"+fn label_F = Values["Label_Dir"] + "\\" + Values["Img_File"][fn] if(os.path.exists(label_F)==False): file = open(label_F,'w') file.close() Values["Cur_Rt"] = [] else: Values["Cur_Rt"] = [] file = open(label_F,'r') cline = file.readline() while(cline): cline = cline.split() T = [0,0,0,0,0] T[0] = int(cline[0]) T[1] = float(cline[1]) T[2] = float(cline[2]) T[3] = float(cline[3]) T[4] = float(cline[4]) T[1] = T[1] - T[3]/2 T[2] = T[2] - T[4]/2 Values["Cur_Rt"].append(T) cline = file.readline() file.close() img = Image.open(fname) w = img.size[0] h = img.size[1] v1 = 1 if(w<h and h>600): v1 = h / 600 h /= v1 w /= v1 elif(w>h and w>1100): v1 = w / 1100 w /= v1 h /= v1 w = int(w) h = int(h) if(Values["Img_Data"]!=0): bottom_Canvas.delete(Values["Img_Data"]) img = img.resize((w,h)) Values["Img_Data"] = ImageTk.PhotoImage(img) sx = (1200 - w ) //2 sy = (650 - h) //2 Values["Cur_Size"] = [sx,sy,w,h] bottom_Canvas.delete(tk.ALL) bottom_Canvas.create_image(sx,sy,anchor='nw', image=Values["Img_Data"]) for rt in Values["Cur_Rt"]: color = colors[rt[0]] x1 = int(w * rt[1])+sx y1 = int(h * rt[2])+sy x2 = int(w * rt[3] + x1) y2 = int(h * rt[4] + y1) bottom_Canvas.create_rectangle(x1,y1,x2,y2,width=2,outline=color) #======================================================= def find_jpg(): global Values Values["Img_File"] = {} Values["nID"] = 0 for root,dirs,files in os.walk(Values["Img_Dir"]): for file in files: if(file.endswith(".jpg") or file.endswith(".JPG") or file.endswith(".jpeg") or file.endswith(".JPEG")): f1 = os.path.splitext(file)[0] Values["Img_File"][file] = f1+".txt" show_img() #======================================================= def prev_bn(): global Values Values["nID"] -=1 show_img() #======================================================= def next_bn(): global Values Values["nID"] +=1 show_img() #======================================================= def clear_bn(): Values["Cur_Rt"] = [] nid = Values["nID"] if(nid >= len(Values["Img_File"])): nid = len(Values["Img_File"])-1 if(nid<0): return fn = get_img(nid) label_F = Values["Label_Dir"] + "\\" + Values["Img_File"][fn] os.remove(label_F) show_img() #======================================================= def OnMouseMove(event): global Values,bottom_Canvas,Ctrl_List,colors if(Values["Sel_Mode"]<0): return if(Values["Tmp_Rt"][0]==0): Values["Tmp_Rt"][0] = 1 Values["Tmp_Rt"][1] = event.x Values["Tmp_Rt"][2] = event.y else: Values["Tmp_Rt"][3] = event.x Values["Tmp_Rt"][4] = event.y if(Values["Tmp_Rt"][5]!=0): bottom_Canvas.delete(Values["Tmp_Rt"][5]) ncolor = colors[Values["Sel_Mode"]] Values["Tmp_Rt"][5] = bottom_Canvas.create_rectangle(Values["Tmp_Rt"][1],Values["Tmp_Rt"][2],Values["Tmp_Rt"][3],Values["Tmp_Rt"][4],width=2,outline=ncolor) #======================================================= def OnRelease(event): global Values,Ctrl_List,Label_List if(Values["Tmp_Rt"][0] ==0): return fn = get_img(Values["nID"]) if(fn==""): return label_F = Values["Label_Dir"] + "\\" + Values["Img_File"][fn] item = Ctrl_List.get() pID = -1 pID = Label_List[item] if(pID==-1): return if(Values["Tmp_Rt"][1] > Values["Tmp_Rt"][3]): t = Values["Tmp_Rt"][1] Values["Tmp_Rt"][1] = Values["Tmp_Rt"][3] Values["Tmp_Rt"][3] = t if(Values["Tmp_Rt"][2] > Values["Tmp_Rt"][4]): t = Values["Tmp_Rt"][1] Values["Tmp_Rt"][2] = Values["Tmp_Rt"][4] Values["Tmp_Rt"][4] = t ff = open(label_F,"a") sx =round((Values["Tmp_Rt"][1]-Values["Cur_Size"][0]) / Values["Cur_Size"][2],4) sy = round((Values["Tmp_Rt"][2]-Values["Cur_Size"][1]) / Values["Cur_Size"][3],4) w = round((Values["Tmp_Rt"][3]-Values["Tmp_Rt"][1] ) / Values["Cur_Size"][2],4) h = round((Values["Tmp_Rt"][4]-Values["Tmp_Rt"][2] ) / Values["Cur_Size"][3],4) sx += w/2 sy += h/2 if(sx<0): sx=0 if(sx>1): sx=1 if(sy<0): sy=0 if(sy>1): sy=1 if(w>1): w=1 if(h>1): h=1 ff.write(str(pID)+" "+str(sx)+" "+str(sy)+" "+ str(w)+" "+ str(h)+"\n") ff.close() Values["Tmp_Rt"][0] = 0 Values["Tmp_Rt"][5] = 0 #======================================================= def ch_Img_Dir(event): global Values,Img_Dir_Label Values["Img_Dir"] = filedialog.askdirectory() Values["Img_Dir"] = Values["Img_Dir"].replace("/","\\") Img_Dir_Label["text"] = Values["Img_Dir"] find_jpg() #====================================================== def ch_Label_Dir(event): global Values,Label_Dir_Label Values["Label_Dir"] = filedialog.askdirectory() Values["Label_Dir"] = Values["Label_Dir"].replace("/","\\") Label_Dir_Label["text"] = Values["Label_Dir"] show_img() #====================================================== def OnSelect(event): global Ctrl_List,Values,Label_List item = Ctrl_List.get() if(item=="清除标签"): Values["Sel_Mode"] = -1 else: Values["Sel_Mode"] = Label_List[item] #====================================================== def Open_Label(): global Label_List Label_List = {} f = open("label.txt",'r',encoding='utf-8') while True: line = f.readline() if(len(line)==0): break tmp = line.split(",") tmp[1] = tmp[1].replace('\n','') Label_List[tmp[0]] = int(tmp[1]) f.close() #====================================================== def Init_GUI(root): global Img_Dir_Label,Label_Dir_Label,bottom_Canvas,Ctrl_List,Label_List font1 = tk.font.Font(family='黑体',size=12); top_Frame = tk.PanedWindow(height=50,bg='#3f3f3f') top_Frame.pack(fill=tk.BOTH,expand=1) Img_Dir_Label = tk.Label(top_Frame,text="图片目录",bg='#7f7f7f',font=font1,fg='white',width=30,height=2) Label_Dir_Label = tk.Label(top_Frame,text="标签目录",bg='#7f7f7f',font=font1,fg='white',width=30,height=2) Img_Dir_Label.bind("<Button-1>",ch_Img_Dir) Label_Dir_Label.bind("<Button-1>",ch_Label_Dir) Prev_Button = tk.Button(top_Frame,text="前一张",bg='#7f7f7f',font=font1,fg='white',width=10,height=2,command=prev_bn) Next_Button = tk.Button(top_Frame,text="后一张",bg='#7f7f7f',font=font1,fg='white',width=10,height=2,command=next_bn) Clear_Button = tk.Button(top_Frame,text="清除标记",bg='#7f7f7f',font=font1,fg='white',width=10,height=2,command=clear_bn) Open_Label() Ctrl_List = ttk.Combobox(top_Frame,font=font1,width=5,state="readonly") TM = [] for key,value in Label_List.items(): TM.append(key) Ctrl_List['value'] = TM Ctrl_List.bind("<ComboboxSelected>",OnSelect) Label_TIP_Label = tk.Label(top_Frame,text="MakeLabel V2021",bg='#7f7f7f',font=font1,fg='white',width=20,height=2) top_Frame.add(Img_Dir_Label) top_Frame.add(Label_Dir_Label) top_Frame.add(Prev_Button) top_Frame.add(Next_Button) top_Frame.add(Ctrl_List) top_Frame.add(Clear_Button) top_Frame.add(Label_TIP_Label) bottom_Canvas = tk.Canvas(root,height=650,bg='#3f3f3f') bottom_Canvas.pack(fill=tk.BOTH,expand=1) bottom_Canvas.bind("<B1-Motion>",OnMouseMove) bottom_Canvas.bind("<ButtonRelease-1>",OnRelease) #================================================ if __name__ == '__main__': colors =["#ffffff","#ff0000","#00ff00","#0000ff","#7f0000","#007f00","#00007f"] Values = {"nID":0,"Img_Dir":"","Label_Dir":"","Img_File":{},"Img_Data":0,"Tmp_Rt":[0,-1,-1,-1,-1,0],"Cur_Rt":[],"Sel_Mode":0,"Cur_Size":[]} Img_Dir_Label = 0 Label_Dir_Label = 0 bottom_Canvas = 0 Ctrl_List = 0 Label_List = 0; #--------------------- root = tk.Tk() root.title("Make Label") root.resizable(0,0) root.geometry("1200x700+0+0") #s_Width = win32api.GetSystemMetrics(win32con.SM_CXSCREEN) #s_Height = win32api.GetSystemMetrics(win32con.SM_CYSCREEN) #sx = (s_Width-1200)//2 #sy = (s_Height-700)//2 sx=0 sy=0 root.geometry("%sx%s+%s+%s" % (1200,700,sx,sy)) Init_GUI(root) root.mainloop()
桂ICP备11003301号-1 公安备案号:45040302000027 Copyright @ 2021- 2022 By Sun zi chao
阅读统计: 1.93W 文章数量: 76 运行天数: 416天 返回cmnsoft