Files @ f1f8a2421f92
Branch filter:

Location: OneEye/exp/color_sampler.py - annotation

Laman
updated readme
d954258c9613
d954258c9613
d954258c9613
9df0d1a019c5
9df0d1a019c5
002858d37174
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
1874230ef2bd
d954258c9613
9df0d1a019c5
9df0d1a019c5
6180b3bd7f3f
79c410b194c6
79c410b194c6
79c410b194c6
9df0d1a019c5
1874230ef2bd
1874230ef2bd
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
d954258c9613
d954258c9613
ac065d1dfcab
1874230ef2bd
002858d37174
d954258c9613
d954258c9613
9df0d1a019c5
9df0d1a019c5
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
9df0d1a019c5
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
9df0d1a019c5
9df0d1a019c5
9c78e6f2e2ea
9c78e6f2e2ea
9c78e6f2e2ea
9df0d1a019c5
9df0d1a019c5
d954258c9613
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
ac065d1dfcab
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
002858d37174
002858d37174
9df0d1a019c5
002858d37174
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
ac065d1dfcab
1874230ef2bd
ac065d1dfcab
1874230ef2bd
ac065d1dfcab
ac065d1dfcab
9df0d1a019c5
9df0d1a019c5
d954258c9613
9df0d1a019c5
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
d954258c9613
d954258c9613
1874230ef2bd
d954258c9613
d954258c9613
a9c02a5b2bfc
a9c02a5b2bfc
a9c02a5b2bfc
a9c02a5b2bfc
a9c02a5b2bfc
a9c02a5b2bfc
a9c02a5b2bfc
a9c02a5b2bfc
002858d37174
002858d37174
002858d37174
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
a9c02a5b2bfc
002858d37174
d954258c9613
9c78e6f2e2ea
9df0d1a019c5
d954258c9613
d954258c9613
9df0d1a019c5
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
9df0d1a019c5
9df0d1a019c5
d954258c9613
d954258c9613
d954258c9613
9df0d1a019c5
9df0d1a019c5
ac065d1dfcab
ac065d1dfcab
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
1874230ef2bd
1874230ef2bd
1874230ef2bd
a9c02a5b2bfc
a9c02a5b2bfc
a9c02a5b2bfc
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
1874230ef2bd
1874230ef2bd
a9c02a5b2bfc
a9c02a5b2bfc
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
a9c02a5b2bfc
a9c02a5b2bfc
a9c02a5b2bfc
a9c02a5b2bfc
a9c02a5b2bfc
ac065d1dfcab
ac065d1dfcab
ac065d1dfcab
a9c02a5b2bfc
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
1874230ef2bd
d954258c9613
9df0d1a019c5
79c410b194c6
6180b3bd7f3f
6180b3bd7f3f
6180b3bd7f3f
6180b3bd7f3f
import sys
sys.path.append("../src")

import os
import tkinter as tk
from tkinter import LEFT,N,S,E,W
from colorsys import rgb_to_hsv

from PIL import Image,ImageTk

from annotations import DataFile,Board


class Sampler:
	def __init__(self,dirname,annotations):
		self.dirname=dirname
		self.annotations=DataFile(annotations)
		self.filenames=[f for f in sorted(os.listdir(self.dirname)) if f.endswith(".jpg")]
		self.k=0
		self.asterisk=False
		self.isGrid=False

		self.img=None
		self.photo=None

		self.letter="_"
		self.hsv=(0,0,0)
		self.pos=(0,0)
		self.m=0
		self._boards=[]
		self._dirty=False

		self._createGUI()

	def sample(self,e):
		try:
			(r,g,b)=(x/255 for x in self.img.getpixel((e.x,e.y)))
		except IndexError:
			return

		(h,s,v)=map(lambda x: round(x,3), rgb_to_hsv(r,g,b))
		self.hsv=(h,s,v)
		self.pos=(e.x,e.y)
		self.posLabel.configure(text="({0},{1})".format(e.x,e.y))
		self.colorLabel.configure(text="HSV: ({0}, {1}, {2})".format(round(h*360),s,v))

	def printSample(self):
		print("\t".join(map(str, (self.filenames[self.k],*self.pos,self.letter,*self.hsv))))

	def showImage(self):
		filename=self.filenames[self.k]
		self.img=Image.open(os.path.join(self.dirname,filename))
		self.root.title(filename)
		(w,h)=self.img.size
		self.photo=ImageTk.PhotoImage(self.img)
		self.canvas.delete("all")
		self.canvas.create_image(0,0,image=self.photo,anchor="nw")
		self.canvas.configure(width=w,height=h)

		self.m=0
		self.isGrid=False
		f=self.filename
		if f in self.annotations:
			self._boards=self.annotations[f]+[Board()]
		else:
			self._boards=[Board()]
		self._markCorners()

	def switchImage(self,step):
		self.save()
		n=len(self.filenames)
		self.k=(self.k+step+n)%n
		self.showImage()

	def switchCorners(self,step):
		n=len(self._boards)
		self.m=(self.m+step+n)%n
		self.isGrid=False
		self._markCorners()

	def setLetter(self,c):
		self.letter=c
		self.letterLabel.configure(text="Letter: {0}".format(c))

	def switchAsterisk(self):
		self.asterisk=not self.asterisk
		self.asteriskLabel.configure(text="*" if self.asterisk else "()")
		self._markCorners()

	def switchGrid(self):
		self.isGrid=not self.isGrid
		self._markCorners()

	def deleteBoard(self):
		self._boards.pop(self.m)
		self._flush()
		self.showImage()

	def addCorner(self,e):
		self.corners.add(e.x,e.y)
		self._flush()
		self._markCorners()

	def setGrade(self,g):
		self.board.setGrade(g)
		self._flush()
		if len([b for b in self._boards if not b.isEmpty()])>1:
			self.switchCorners(1)
		else:
			self.switchImage(1)

	def save(self):
		if self._dirty:
			self.annotations.save()
			self._dirty=False

	def _flush(self):
		self.annotations[self.filename]=[b for b in self._boards if not b.isEmpty()]
		self._dirty=True

	def _createGUI(self):
		self.root=root=tk.Tk()
		frame=tk.Frame(root)
		frame.grid(column=0,row=0,sticky=(N,S,E,W))

		self.canvas=tk.Canvas(frame)
		self.canvas.grid(row=1,column=0)

		bar=self._createBar(frame)
		bar.grid(row=2,column=0,sticky=(E,W))

		self.showImage()

		self.canvas.bind('<1>',lambda e: self.printSample())
		self.canvas.bind('<3>',self.addCorner)
		self.canvas.bind("<Motion>",self.sample)
		root.bind("<Left>",lambda e: self.switchImage(-1))
		root.bind("<Right>",lambda e: self.switchImage(1))
		root.bind("<Up>",lambda e: self.switchCorners(-1))
		root.bind("<Down>",lambda e: self.switchCorners(1))
		root.bind("<b>",lambda e: self.setLetter("b"))
		root.bind("<e>",lambda e: self.setLetter("e"))
		root.bind("<w>",lambda e: self.setLetter("w"))
		root.bind("<Key-period>",lambda e: self.switchAsterisk())
		root.bind("<Key-comma>",lambda e: self.switchGrid())
		root.bind("<d>",lambda e: self.deleteBoard())
		root.bind("<Key-1>",lambda e: self.setGrade(Board.CLEAR))
		root.bind("<Key-2>",lambda e: self.setGrade(Board.GOOD))
		root.bind("<Key-3>",lambda e: self.setGrade(Board.POOR))

		root.mainloop()

	def _createBar(self,frame):
		bar=tk.Frame(frame,height=20,borderwidth=1,relief="sunken")
		self.letterLabel=tk.Label(bar,width=8,text="Letter: _")
		self.letterLabel.pack(side=LEFT)
		self.posLabel=tk.Label(bar,width=16,text="(,)")
		self.posLabel.pack(side=LEFT)
		self.colorLabel=tk.Label(bar,width=20,text="HSV: (,,)")
		self.colorLabel.pack(side=LEFT)
		self.asteriskLabel=tk.Label(bar,width=4,text="()")
		self.asteriskLabel.pack(side=LEFT)
		self.gradeLabel=tk.Label(bar,width=8,text="")
		self.gradeLabel.pack(side=LEFT)

		return bar

	def _markCorners(self):
		self.canvas.delete("mark")
		for b in self._boards:
			for corners in (b.board,b.grid):
				for c in corners:
					(x,y)=(c.x,c.y)
					self.canvas.create_oval(x-2,y-2,x+2,y+2,fill="#00ff00",tags="mark")
				if corners.is_canon():
					(a,b,c,d)=corners
					dash=tuple() if corners is self.corners else (4,4)
					self.canvas.create_line(a.x,a.y,b.x,b.y,fill="#00ff00",dash=dash,tags="mark")
					self.canvas.create_line(b.x,b.y,c.x,c.y,fill="#00ff00",dash=dash,tags="mark")
					self.canvas.create_line(c.x,c.y,d.x,d.y,fill="#00ff00",dash=dash,tags="mark")
					self.canvas.create_line(d.x,d.y,a.x,a.y,fill="#00ff00",dash=dash,tags="mark")
		self.gradeLabel.configure(text=Board.labels[self.board.grade])

	@property
	def board(self):
		return self._boards[self.m]

	@property
	def corners(self):
		b=self.board
		return b.grid if self.isGrid else b.board

	@property
	def filename(self):
		return "." if self.asterisk else self.filenames[self.k]


if __name__=="__main__":
	dirname=sys.argv[1]
	annotations=sys.argv[2]

	s=Sampler(dirname,annotations)