Files @ 3203933cf112
Branch filter:

Location: OneEye/exp/color_sampler.py - annotation

Laman
createsamples
d954258c9613
d954258c9613
d954258c9613
9df0d1a019c5
002858d37174
002858d37174
002858d37174
9df0d1a019c5
002858d37174
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
002858d37174
d954258c9613
d954258c9613
9df0d1a019c5
79c410b194c6
79c410b194c6
79c410b194c6
79c410b194c6
9df0d1a019c5
9df0d1a019c5
79c410b194c6
79c410b194c6
79c410b194c6
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
d954258c9613
d954258c9613
d954258c9613
002858d37174
d954258c9613
d954258c9613
9df0d1a019c5
9df0d1a019c5
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
9df0d1a019c5
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
d954258c9613
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
002858d37174
002858d37174
002858d37174
9df0d1a019c5
002858d37174
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
d954258c9613
9df0d1a019c5
d954258c9613
d954258c9613
002858d37174
002858d37174
d954258c9613
d954258c9613
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
d954258c9613
9df0d1a019c5
9df0d1a019c5
d954258c9613
d954258c9613
9df0d1a019c5
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
9df0d1a019c5
9df0d1a019c5
d954258c9613
d954258c9613
d954258c9613
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
d954258c9613
9df0d1a019c5
002858d37174
79c410b194c6
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
002858d37174
79c410b194c6
79c410b194c6
import sys
sys.path.append("../src")

import os
import json
import gzip
from collections.abc import MutableMapping
import tkinter as tk
from tkinter import LEFT,N,S,E,W
from colorsys import rgb_to_hsv

from PIL import Image,ImageTk

from analyzer.epoint import EPoint
from analyzer.corners import Corners


dirname=sys.argv[1]
annotations=sys.argv[2]


class Sampler:
	def __init__(self):
		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.img=None
		self.photo=None

		self.letter="_"
		self.hsv=(0,0,0)
		self.pos=(0,0)
		self.corners=Corners()
		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):
		self.img=Image.open(os.path.join(self.dirname,self.filenames[self.k]))
		(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.corners=Corners(self.annotations.get(self.filenames[self.k]) or [])
		self._markCorners()

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

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

	def addCorner(self,e):
		self.corners.add(e.x,e.y)
		self.annotations[self.filenames[self.k]]=list(self.corners)
		self._dirty=True
		self._markCorners()

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

	def _createGUI(self):
		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("<b>",lambda e: self.setLetter("b"))
		root.bind("<e>",lambda e: self.setLetter("e"))
		root.bind("<w>",lambda e: self.setLetter("w"))

		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)

		return bar

	def _markCorners(self):
		self.canvas.delete("mark")
		for c in self.corners:
			(x,y)=(c.x,c.y)
			self.canvas.create_oval(x-2,y-2,x+2,y+2,fill="#00ff00",tags="mark")
		if self.corners.canonizeOrder():
			(a,b,c,d)=self.corners
			self.canvas.create_line(a.x,a.y,b.x,b.y,fill="#00ff00",tags="mark")
			self.canvas.create_line(b.x,b.y,c.x,c.y,fill="#00ff00",tags="mark")
			self.canvas.create_line(c.x,c.y,d.x,d.y,fill="#00ff00",tags="mark")
			self.canvas.create_line(d.x,d.y,a.x,a.y,fill="#00ff00",tags="mark")


class DataFile(MutableMapping):
	"""self._data: {filename: [EPoint,EPoint,EPoint,EPoint]}"""
	def __init__(self,filename):
		self.filename=filename
		try:
			with gzip.open(filename,mode="rt",encoding="utf8") as f:
				self._data=json.load(f,object_hook=self.deserialize)
		except OSError:
			self._data=dict()

	def save(self):
		with gzip.open(self.filename,mode="wt",encoding="utf8") as f:
			json.dump(self._data,f,default=self.serialize,indent="\t")

	def serialize(self,obj):
		if isinstance(obj,EPoint):
			return {"type": "EPoint", "val": [obj.x,obj.y]}
		raise TypeError(obj)

	def deserialize(self,obj):
		if obj.get("type")!="EPoint": return obj
		return EPoint(*obj["val"])

	def __getitem__(self, key): return self._data[key]
	def __setitem__(self, key, val): self._data[key]=val
	def __delitem__(self, key): del self._data[key]
	def __iter__(self): return iter(self._data)
	def __len__(self): return len(self._data)


if __name__=="__main__":
	s=Sampler()