Files @ 1d1fd2ae49bf
Branch filter:

Location: OneEye/exp/color_sampler.py - annotation

Laman
collector improved
d954258c9613
d954258c9613
d954258c9613
9df0d1a019c5
002858d37174
002858d37174
002858d37174
9df0d1a019c5
002858d37174
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
002858d37174
d954258c9613
d954258c9613
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
9df0d1a019c5
002858d37174
9df0d1a019c5
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
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
9df0d1a019c5
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


class Sampler:
	def __init__(self):
		self.dirname="../images"
		self.annotations=DataFile("annotations.json.gz")
		self.filenames=[f for f in 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):
	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)


s=Sampler()