有时候需要对于数据集进行预处理,通过标注获取坐标信息,再进行后续的操作。使用python能够快速读取图片,并能够通过人工标注,记录一下每个点的横竖坐标,如下记录学习笔记。

参考链接:https://lcqbit11.blog.csdn.net/article/details/69951249

参考链接:https://blog.csdn.net/wuzuyu365/article/details/52523061?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-2&spm=1001.2101.3001.4242

参考链接:https://blog.csdn.net/qq_26697045/article/details/101461525

参考链接:https://www.jb51.net/article/157968.htm

源码

整个目录的结构如下:

根目录

——images:存放图片

——outputs:存放标注坐标信息

图片存放位置:E:\Python\biaozhu\images\001(图片仅仅是用来测试的,应存放数据集)

from __future__ import division
import tkinter as tk
from tkinter import Frame
from tkinter import BOTH
from tkinter import *
import tkinter.messagebox
from PIL import Image, ImageTk
import os
import glob
import random  w0 = 1; #图片原始宽度
h0 = 1; #图片原始高度  # colors for the bboxes
COLORS = ['red', 'blue', 'yellow', 'pink', 'cyan', 'green', 'black']
# image sizes for the examples
SIZE = 960, 600  #指定缩放后的图像大小
DEST_SIZE = 960, 600   class LabelTool():  def __init__(self, master):  # set up the main frame  self.parent = master  self.parent.title("图像标注")  self.frame = Frame(self.parent)  self.frame.pack(fill=BOTH, expand=1)  self.parent.resizable(width = TRUE, height = TRUE)  # initialize global state  self.imageDir = ''  self.imageList= []  self.egDir = ''  self.egList = []  self.outDir = ''  self.cur = 0  self.total = 0  self.category = 0  self.imagename = ''  self.labelfilename = ''  self.tkimg = None  # initialize mouse state  self.STATE = {}  self.STATE['click'] = 0  self.STATE['x'], self.STATE['y'] = 0, 0  # reference to bbox  self.bboxIdList = []  self.bboxId = None  self.bboxList = []  self.hl = None  self.vl = None  # ----------------- GUI stuff ---------------------  # dir entry & load  self.label = Label(self.frame, text = "Image Dir:")  self.label.grid(row = 0, column = 0, sticky = E)  self.entry = Entry(self.frame)  self.entry.grid(row = 0, column = 1, sticky = W+E)  self.ldBtn = Button(self.frame, text = "Load", command = self.loadDir)  self.ldBtn.grid(row = 0, column = 2, sticky = W+E)  # main panel for labeling  self.mainPanel = Canvas(self.frame, cursor='tcross')  self.mainPanel.bind("<Button-1>", self.mouseClick)  self.mainPanel.bind("<Motion>", self.mouseMove)  self.parent.bind("<Escape>", self.cancelBBox)  # press <Espace> to cancel current bbox  self.parent.bind("s", self.cancelBBox)  self.parent.bind("a", self.prevImage) # press 'a' to go backforward  self.parent.bind("d", self.nextImage) # press 'd' to go forward  self.mainPanel.grid(row = 1, column = 1, rowspan = 4, sticky = W+N)  # showing bbox info & delete bbox  self.lb1 = Label(self.frame, text = 'Bounding boxes:')  self.lb1.grid(row = 1, column = 2,  sticky = W+N)  self.listbox = Listbox(self.frame, width = 28, height = 12)  self.listbox.grid(row = 2, column = 2, sticky = N)  self.btnDel = Button(self.frame, text = 'Delete', command = self.delBBox)  self.btnDel.grid(row = 3, column = 2, sticky = W+E+N)  self.btnClear = Button(self.frame, text = 'ClearAll', command = self.clearBBox)  self.btnClear.grid(row = 4, column = 2, sticky = W+E+N)  # control panel for image navigation  self.ctrPanel = Frame(self.frame)  self.ctrPanel.grid(row = 5, column = 1, columnspan = 2, sticky = W+E)  self.prevBtn = Button(self.ctrPanel, text='<< Prev', width = 10, command = self.prevImage)  self.prevBtn.pack(side = LEFT, padx = 5, pady = 3)  self.nextBtn = Button(self.ctrPanel, text='Next >>', width = 10, command = self.nextImage)  self.nextBtn.pack(side = LEFT, padx = 5, pady = 3)  self.progLabel = Label(self.ctrPanel, text = "Progress:     /    ")  self.progLabel.pack(side = LEFT, padx = 5)  self.tmpLabel = Label(self.ctrPanel, text = "Go to Image No.")  self.tmpLabel.pack(side = LEFT, padx = 5)  self.idxEntry = Entry(self.ctrPanel, width = 5)  self.idxEntry.pack(side = LEFT)  self.goBtn = Button(self.ctrPanel, text = 'Go', command = self.gotoImage)  self.goBtn.pack(side = LEFT)  # example pannel for illustration  self.egPanel = Frame(self.frame, border = 10)  self.egPanel.grid(row = 1, column = 0, rowspan = 5, sticky = N)  self.tmpLabel2 = Label(self.egPanel, text = "Examples:")  self.tmpLabel2.pack(side = TOP, pady = 5)  self.egLabels = []  for i in range(3):  self.egLabels.append(Label(self.egPanel))  self.egLabels[-1].pack(side = TOP)  # display mouse position  self.disp = Label(self.ctrPanel, text='')  self.disp.pack(side = RIGHT)  self.frame.columnconfigure(1, weight = 1)  self.frame.rowconfigure(4, weight = 1)  # for debugging
##        self.setImage()
##        self.loadDir()  def loadDir(self, dbg = False):  if not dbg:  s = self.entry.get()  self.parent.focus()  self.category = int(s)  else:  s = r'E:/Python/get_picture/picture'
##        if not os.path.isdir(s):
##            tkMessageBox.showerror("Error!", message = "The specified dir doesn't exist!")
##            return  # get image list  print('self.category =%d'  %(self.category ) ) self.imageDir = os.path.join(r'./images', '%03d' %(self.category))  print("imageDir=",self.imageDir)   self.imageList = glob.glob(os.path.join(self.imageDir, '*.jpg'))  if len(self.imageList) == 0:  print('No .jpg images found in the specified dir!'  )return  else:  print('num=%d'  %(len(self.imageList)) ) # default to the 1st image in the collection  self.cur = 1  self.total = len(self.imageList)  # set up output dir  self.outDir = os.path.join(r'./outputs', '%03d' %(self.category))  if not os.path.exists(self.outDir):  os.mkdir(self.outDir)  # load example bboxes  self.egDir = os.path.join(r'./Examples', '%03d' %(self.category))  #if not os.path.exists(self.egDir):  #   return  filelist = glob.glob(os.path.join(self.egDir, '*.jpg'))  self.tmp = []  self.egList = []  random.shuffle(filelist)  for (i, f) in enumerate(filelist):  if i == 3:  break  im = Image.open(f)  r = min(SIZE[0] / im.size[0], SIZE[1] / im.size[1])  new_size = int(r * im.size[0]), int(r * im.size[1])  self.tmp.append(im.resize(new_size, Image.ANTIALIAS))  self.egList.append(ImageTk.PhotoImage(self.tmp[-1]))  self.egLabels[i].config(image = self.egList[-1], width = SIZE[0], height = SIZE[1])  self.loadImage()  print('%d images loaded from %s' %(self.total, s))  def loadImage(self):  # load image  imagepath = self.imageList[self.cur - 1]  pil_image = Image.open(imagepath)  # get the size of the image  #获取图像的原始大小  global w0,h0  w0, h0 = pil_image.size  #缩放到指定大小  pil_image = pil_image.resize((DEST_SIZE[0], DEST_SIZE[1]), Image.ANTIALIAS)  #pil_image = imgresize(w, h, w_box, h_box, pil_image)  self.img =  pil_image  self.tkimg = ImageTk.PhotoImage(pil_image)  self.mainPanel.config(width = max(self.tkimg.width(), 400), height = max(self.tkimg.height(), 400))   self.mainPanel.create_image(0, 0, image = self.tkimg, anchor=NW)  self.progLabel.config(text = "%04d/%04d" %(self.cur, self.total))  # load labels  self.clearBBox()  self.imagename = os.path.split(imagepath)[-1].split('.')[0]  labelname = self.imagename + '.txt'  self.labelfilename = os.path.join(self.outDir, labelname)  bbox_cnt = 0  if os.path.exists(self.labelfilename):  with open(self.labelfilename) as f:  for (i, line) in enumerate(f):  if i == 0:  bbox_cnt = int(line.strip())  continue  print(line)   tmp = [(t.strip()) for t in line.split()]  print("********************" ) print( DEST_SIZE)  #tmp = (0.1, 0.3, 0.5, 0.5)  print("tmp[0,1,2,3]===%.2f, %.2f, %.2f, %.2f" %(float(tmp[0]), float(tmp[1]), float(tmp[2]), float(tmp[3])))  #print "%.2f,%.2f,%.2f,%.2f" %(tmp[0] tmp[1] tmp[2] tmp[3] )  print("********************")  #tx = (10, 20, 30, 40)    #self.bboxList.append(tuple(tx))  self.bboxList.append(tuple(tmp))  tmp[0] = float(tmp[0])       tmp[1] = float(tmp[1])  tmp[2] = float(tmp[2])       tmp[3] = float(tmp[3])  tx0 = int(tmp[0]*DEST_SIZE[0])  ty0 = int(tmp[1]*DEST_SIZE[1])  tx1 = int(tmp[2]*DEST_SIZE[0])  ty1 = int(tmp[3]*DEST_SIZE[1])  print("tx0, ty0, tx1, ty1")  print(tx0, ty0, tx1, ty1)  tmpId = self.mainPanel.create_rectangle(tx0, ty0, tx1, ty1, width = 2, outline = COLORS[(len(self.bboxList)-1) % len(COLORS)])  self.bboxIdList.append(tmpId)  self.listbox.insert(END, '(%.2f,%.2f)-(%.2f,%.2f)' %(tmp[0], tmp[1], tmp[2], tmp[3]) )  # self.listbox.insert(END, '(%d, %d) -> (%d, %d)' %(tmp[0], tmp[1], tmp[2], tmp[3]))  self.listbox.itemconfig(len(self.bboxIdList) - 1, fg = COLORS[(len(self.bboxIdList) - 1) % len(COLORS)])  def saveImage(self):  #print "-----1--self.bboxList---------"  print(self.bboxList)   #print "-----2--self.bboxList---------"  with open(self.labelfilename, 'w') as f:  f.write('%d\n' %len(self.bboxList))  for bbox in self.bboxList:   f.write(' '.join(map(str, bbox)) + '\n')  print('Image No. %d saved' %(self.cur))  def mouseClick(self, event):  if self.STATE['click'] == 0:  self.STATE['x'], self.STATE['y'] = event.x, event.y  else:  x1, x2 = min(self.STATE['x'], event.x), max(self.STATE['x'], event.x)  y1, y2 = min(self.STATE['y'], event.y), max(self.STATE['y'], event.y)  x1, x2 = x1 / DEST_SIZE[0], x2 / DEST_SIZE[0];   y1, y2 = y1 / DEST_SIZE[1], y2 / DEST_SIZE[1];   self.bboxList.append((x1, y1, x2, y2))  self.bboxIdList.append(self.bboxId)  self.bboxId = None  self.listbox.insert(END, '(%.2f, %.2f)-(%.2f, %.2f)' %(x1, y1, x2, y2))  self.listbox.itemconfig(len(self.bboxIdList) - 1, fg = COLORS[(len(self.bboxIdList) - 1) % len(COLORS)])  self.STATE['click'] = 1 - self.STATE['click']  def mouseMove(self, event):  self.disp.config(text = 'x: %.2f, y: %.2f' %(event.x/DEST_SIZE[0], event.y/DEST_SIZE[1]))  if self.tkimg:  if self.hl:  self.mainPanel.delete(self.hl)  self.hl = self.mainPanel.create_line(0, event.y, self.tkimg.width(), event.y, width = 2)  if self.vl:  self.mainPanel.delete(self.vl)  self.vl = self.mainPanel.create_line(event.x, 0, event.x, self.tkimg.height(), width = 2)  if 1 == self.STATE['click']:  if self.bboxId:  self.mainPanel.delete(self.bboxId)  self.bboxId = self.mainPanel.create_rectangle(self.STATE['x'], self.STATE['y'], event.x, event.y, width = 2, outline = COLORS[len(self.bboxList) % len(COLORS)])  def cancelBBox(self, event):  if 1 == self.STATE['click']:  if self.bboxId:  self.mainPanel.delete(self.bboxId)  self.bboxId = None  self.STATE['click'] = 0  def delBBox(self):  sel = self.listbox.curselection()  if len(sel) != 1 :  return  idx = int(sel[0])  self.mainPanel.delete(self.bboxIdList[idx])  self.bboxIdList.pop(idx)  self.bboxList.pop(idx)  self.listbox.delete(idx)  def clearBBox(self):  for idx in range(len(self.bboxIdList)):  self.mainPanel.delete(self.bboxIdList[idx])  self.listbox.delete(0, len(self.bboxList))  self.bboxIdList = []  self.bboxList = []  def prevImage(self, event = None):  self.saveImage()  if self.cur > 1:  self.cur -= 1  self.loadImage()  def nextImage(self, event = None):  self.saveImage()  if self.cur < self.total:  self.cur += 1  self.loadImage()  def gotoImage(self):  idx = int(self.idxEntry.get())  if 1 <= idx and idx <= self.total:  self.saveImage()  self.cur = idx  self.loadImage()  ##    def setImage(self, imagepath = r'test2.png'):
##        self.img = Image.open(imagepath)
##        self.tkimg = ImageTk.PhotoImage(self.img)
##        self.mainPanel.config(width = self.tkimg.width())
##        self.mainPanel.config(height = self.tkimg.height())
##        self.mainPanel.create_image(0, 0, image = self.tkimg, anchor=NW)  def imgresize(w, h, w_box, h_box, pil_image):  ''''' resize a pil_image object so it will fit into a box of size w_box times h_box, but retain aspect ratio '''  f1 = 1.0*w_box/w # 1.0 forces float division in Python2  f2 = 1.0*h_box/h  factor = min([f1, f2])  #print(f1, f2, factor) # test  # use best down-sizing filter  width = int(w*factor)  height = int(h*factor)  return pil_image.resize((width, height), Image.ANTIALIAS)  if __name__ == '__main__':  root = tk.Tk()  tool = LabelTool(root)  root.mainloop()

效果

由于代码中将路径设置为:

self.imageDir = os.path.join(r'./images', '%03d' %(self.category))
print("imageDir=",self.imageDir)

所以,不需要输入001,只需要输入1即可。

然后,得到的图像标注坐标为:

python实现一个简单的【图像中物体坐标】标注小工具相关推荐

  1. python绘制一个简单的函数图像使用到了matplotlib库和numpy库

    文章目录 效果展示: 视频链接 实现的思想 使用到的函数包 图片一对应的代码展示 图片二 对应的代码展示 注意事项 效果展示: 视频链接 python绘制一个简单的函数图像(B站视频) 实现的思想 其 ...

  2. Python实现一个简单的目标检测

    Python实现一个简单的目标检测 相关介绍 实验环境 基本思路 代码实现 输出结果 相关介绍 选择性搜索(Select Search)算法属于候选区域算法,用分割不同区域的办法来识别潜在的物体.在分 ...

  3. python编写一个登陆验证程序_用python实现一个简单的验证码

    我们经常在登录一个网站,或者注册的时候需要输入一个验证码,有时候觉得很烦,因为有些验证码不仅复杂还看不清,许多用户就会因为这些而懒得再登录或者注册之类的. 既然验证码会造成流失用户的风险,为什么大家都 ...

  4. 用python做一个简单GUI小软件

    用python做一个简单软件 前言 这是一个课设,用python做一个扫描王软件 我主要做的GUI部分,记录分享一下.也是第一次用python做小软件,python的方便果然是名不虚传 遇到问题 1. ...

  5. 编程实战(4)——python识别图像中的坐标点并保存坐标数据

    编程实战(4)--python识别图像中的坐标点并保存坐标数据 文章目录 编程实战(4)--python识别图像中的坐标点并保存坐标数据 综述 代码思路 库的安装 图片预处理 图像细化 图像二极化 提 ...

  6. 用python做一个简单的游戏,用python写一个小游戏

    大家好,本文将围绕如何用python做一个简单的小游戏展开说明,python编写的入门简单小游戏是一个很多人都想弄明白的事情,想搞清楚用python做一个简单的游戏需要先了解以下几个事情. 1.Pyt ...

  7. python实现一个简单的项目建议书范文_建议收藏,22个Python迷你项目(附源码)

    Python部落在使用Python的过程中,我最喜欢的就是Python的各种第三方库,能够完成很多操作. 下面就给大家介绍22个通过Python构建的项目,以此来学习Python编程. 大家也可根据项 ...

  8. python实现一个简单的项目建议书范文_建议收藏,18个Python迷你项目(附源码)

    在使用Python的过程中,我最喜欢的就是Python的各种第三方库,能够完成很多操作. 下面就给大家介绍22个通过Python构建的项目,以此来学习Python编程. 大家也可根据项目的目的及提示, ...

  9. 使用OpenCV测量图像中物体的大小

    本文翻译自pyimagesearch技术博客上的一篇文章,<Measuring size of objects in an image with OpenCV>,原文作者:Adrian R ...

最新文章

  1. 【codeforces 242E】XOR on Segment
  2. JS保留4位小数(合集)
  3. Eclipse如何提高开发效率
  4. android 半浮层框架,GitHub - Jodragon/AnyLayer: Android稳定高效的浮层创建管理框架
  5. 文件I0通用的IO模型
  6. centos6.5安装mongodb2.6
  7. EPS 转 pdf 在线
  8. Bootstrap+DataTables后端排序分页详解
  9. 开源:Taurus.MVC 框架 (已支持.NET Core)
  10. 默认情况下linux主机在机房托管期间被,托管机房作业未传之秘
  11. 泰坦尼克号数据集下载
  12. android 展开收起功能,Android非常简单的TextView展开和收起,在列表中TextView文章展开全部和收起...
  13. 数学分析教程(科大)——6.4笔记+习题
  14. macd ema java源码_MACD指标源码汇总,成功率极高,买卖点提前一目了然!
  15. 通过负载均衡器+域名实现容灾切换-(11)深信服负载均衡器
  16. 阿里云服务器被攻击危害有多大
  17. 2022年郑州市初级焊工考试模拟试题及答案
  18. linux系统中同时开启wifi与热点的办法
  19. NOIP2021 T3 方差
  20. 2017JAVA秋招总结

热门文章

  1. CSS-Position用法的理解
  2. php路径伪静态化,URL地址伪静态化
  3. 使用vue-cli来搭建vue项目
  4. LeetCode 674 最长连续递增子序列
  5. Windows平台下NS2网络仿真环境的搭建
  6. python的整除运算_Python3基础 ** 幂运算 // 整除运算
  7. ubuntu服务器系统不识别,U盘安装16.04server版 安装好后重启 无法进入系统
  8. 台式计算机华硕电源,美声大师+智能电源 华硕台式电脑M51AC
  9. mysql 生成短网址_生成短链接的URL
  10. 语言 泰克示波器程序_示波器再升级,EMI测试不求人