diff --git a/exp/color_sampler.py b/exp/color_sampler.py --- a/exp/color_sampler.py +++ b/exp/color_sampler.py @@ -2,18 +2,23 @@ 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,X,N,S,E,W +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 @@ -24,6 +29,7 @@ class Sampler: self.hsv=(0,0,0) self.pos=(0,0) self.corners=Corners() + self._dirty=False self._createGUI() @@ -50,7 +56,11 @@ class Sampler: 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() @@ -61,8 +71,15 @@ class Sampler: 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) @@ -111,4 +128,33 @@ class Sampler: 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() diff --git a/src/analyzer/corners.py b/src/analyzer/corners.py --- a/src/analyzer/corners.py +++ b/src/analyzer/corners.py @@ -6,8 +6,8 @@ log=logging.getLogger(__name__) class Corners: - def __init__(self): - self._corners=[] + def __init__(self,cornerList=[]): + self._corners=cornerList[:] ## Adds a new corner if there are less than four, replaces the closest otherwise. def add(self,x,y):