Changeset - a9c02a5b2bfc
[Not reviewed]
default
0 3 0
Laman - 6 years ago 2019-05-28 13:48:11

grading annotated data
3 files changed with 49 insertions and 7 deletions:
0 comments (0 inline, 0 general)
exp/annotations.py
Show inline comments
 
@@ -7,18 +7,28 @@ from typing import MutableMapping
 

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

	
 

	
 
class Board:
 
	labels=["UNSET","CLEAR","GOOD","POOR"]
 
	UNSET=0
 
	CLEAR=1
 
	GOOD=2
 
	POOR=3
 

	
 
	def __init__(self,**kwargs):
 
		self.board=Corners(kwargs.get("board") or [])
 
		self.grid=Corners(kwargs.get("grid") or [])
 
		self.grade=kwargs.get("grade") or Board.UNSET
 

	
 
	def isEmpty(self):
 
		return len(self.board)==0 and len(self.grid)==0
 
		return len(self.board)==0 and len(self.grid)==0 and self.grade==Board.UNSET
 

	
 
	def setGrade(self,g):
 
		self.grade=g
 

	
 

	
 
class DataFile(MutableMapping):
 
	"""self.data: {filename: [Board, ...}"""
 
	def __init__(self,filename):
 
		self.filename=filename
 
@@ -33,13 +43,13 @@ class DataFile(MutableMapping):
 
			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]}
 
		elif isinstance(obj,Board):
 
			return {"type": "Board", "val": {"board": list(obj.board), "grid": list(obj.grid)}}
 
			return {"type": "Board", "val": {"board": list(obj.board), "grid": list(obj.grid), "grade": obj.grade}}
 
		raise TypeError(obj)
 

	
 
	def deserialize(self,obj):
 
		type=obj.get("type")
 
		if type=="EPoint": return EPoint(*obj["val"])
 
		elif type=="Board": return Board(**obj["val"])
exp/color_sampler.py
Show inline comments
 
@@ -91,28 +91,35 @@ class Sampler:
 
		self.isGrid=not self.isGrid
 
		self._markCorners()
 

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

	
 
	def addCorner(self,e):
 
		self.corners.add(e.x,e.y)
 
		self._flush()
 
		self._dirty=True
 
		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))
 

	
 
@@ -134,12 +141,15 @@ class Sampler:
 
		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: _")
 
@@ -147,12 +157,14 @@ class Sampler:
 
		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:
 
@@ -164,16 +176,21 @@ class Sampler:
 
					(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._boards[self.m]
 
		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]
 

	
exp/kerokero/prepare_data.py
Show inline comments
 
import os
 
import sys
 
import re
 
import random
 
import logging as log
 

	
 
import numpy as np
 
import cv2 as cv
 

	
 
import config as cfg
 
sys.path.append("..")
 
sys.path.append("../../src")
 
from annotations import DataFile,computeBoundingBox,Corners,EPoint
 
from annotations import DataFile,computeBoundingBox,Corners,EPoint,Board
 
from geometry import Line
 
from kerokero.transformation_matrices import getIdentity,getRotation,getTranslation,getScale,getMirroring,getProjection
 

	
 
random.seed(361)
 

	
 

	
 
class Stats:
 
	counts=[0,0,0,0]
 

	
 

	
 
class Sample:
 
	SIDE=224
 

	
 
	def __init__(self,img,grid):
 
		""":param img: a greyscale image as a 2D np.uint8
 
		:param grid: iterable of 4 EPoints, ie. Corners"""
 
@@ -58,33 +64,37 @@ class Sample:
 
		return np.matmul(scale,t2)
 

	
 
	def show(self):
 
		img=cv.cvtColor(self.img,cv.COLOR_GRAY2BGR)
 
		for c in self.grid:
 
			cv.circle(img,(int(c.x),int(c.y)),3,[0,255,0],-1)
 
		img=cv.resize(img,(self.SIDE*2,self.SIDE*2))
 
		show(img)
 

	
 

	
 
def traverseDirs(root):
 
	stack=[root]
 
	while len(stack)>0:
 
		d=stack.pop()
 
		contents=sorted(os.scandir(d),key=lambda f: f.name,reverse=True)
 
		if any(f.name=="annotations.json.gz" for f in contents):
 
			print(d)
 
			log.info(d)
 
			yield d
 
		for f in contents:
 
			if f.is_dir(): stack.append(f.path)
 

	
 

	
 
def harvestDir(path):
 
	annotations=DataFile(os.path.join(path,"annotations.json.gz"))
 
	imgFilter=lambda f: f.is_file() and re.match(r".*\.(jpg|jpeg|png|gif)$", f.name.lower())
 
	files=sorted(filter(imgFilter,os.scandir(path)),key=lambda f: f.name)
 
	boards=annotations["."]
 
	for f in files:
 
		grade=annotations.get(f.name,[Board()])[0].grade
 
		Stats.counts[grade]+=1
 
		if not Board.UNSET<grade<=Board.POOR: continue
 
		img=cv.imread(f.path)
 
		img=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
 
		for b in boards:
 
			sample=Sample(img,b.grid)
 
			# sample.show()
 
			(transformedImg,label)=sample.transform()
 
@@ -98,12 +108,17 @@ def loadDataset(root):
 
	images=[]
 
	labels=[]
 
	for d in traverseDirs(root):
 
		for (img,label) in harvestDir(d):
 
			images.append(img)
 
			labels.append(label)
 
	log.info("clear images: %s",Stats.counts[1])
 
	log.info("good images: %s",Stats.counts[2])
 
	log.info("poor images: %s",Stats.counts[3])
 
	log.info("unset images: %s",Stats.counts[0])
 
	log.info("total: %s",sum(Stats.counts))
 
	n=len(images)
 
	keys=list(range(n))
 
	random.shuffle(keys)
 
	images=[images[k] for k in keys]
 
	labels=[labels[k] for k in keys]
 
	m=int(n*trainRatio)
0 comments (0 inline, 0 general)