Files @ 247811dfb9be
Branch filter:

Location: OneEye/exp/kerokero/prepare_data.py - annotation

Laman
data augmentation
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
fad34516870e
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
ecf98a415d97
fad34516870e
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
fad34516870e
fad34516870e
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
ecf98a415d97
655956f6ba89
9c78e6f2e2ea
006c6f1aab13
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
ecf98a415d97
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
ecf98a415d97
655956f6ba89
655956f6ba89
655956f6ba89
ecf98a415d97
655956f6ba89
655956f6ba89
d9cf0ed8e7fd
006c6f1aab13
ecf98a415d97
8b30e6dba468
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
ecf98a415d97
ecf98a415d97
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
655956f6ba89
9483b964f560
9483b964f560
9483b964f560
9483b964f560
9483b964f560
9483b964f560
9483b964f560
9483b964f560
import os
import sys
import re
import random

import numpy as np
import cv2 as cv

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

random.seed(361)


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"""
		self.img=img
		self.grid=grid

	def transform(self):
		""":return: (img, grid), where img is a 2D np.float32 with values in (0,1),
		grid [(float) x, (float) y, ...], with x, y in (-1,1)"""
		center=self._getCenter()
		m=getIdentity()
		t1=getTranslation(-center.x,-center.y)
		proj=getProjection()
		rot=getRotation()
		mir=getMirroring()
		for mi in [t1,mir,proj,rot]:
			m=np.matmul(mi,m)
		m=np.matmul(self._computeCrop(m),m)
		img=cv.warpPerspective(self.img,m,(self.SIDE,self.SIDE))
		img=np.float32(img)/128-1
		grid=Corners(c.transform(m) for c in self.grid)
		grid=list(map(lambda p: list(2*p/self.SIDE-EPoint(1,1)), grid))
		return (img,grid)

	def _getCenter(self):
		(a,b,c,d)=self.grid
		p=Line.fromPoints(a,c)
		q=Line.fromPoints(b,d)
		return p.intersect(q)

	def _computeCrop(self,m):
		grid=Corners(c.transform(m) for c in self.grid)
		(x1,y1,x2,y2)=computeBoundingBox(grid)
		(wg,hg)=(x2-x1,y2-y1)
		(left,top,right,bottom)=[random.uniform(0.05,0.2) for i in range(4)]
		t2=getTranslation(left*wg-x1, top*hg-y1)
		scale=getScale(self.SIDE/(wg*(1+left+right)), self.SIDE/(hg*(1+top+bottom)))
		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)
		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)
			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:
		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()
			# Sample(np.uint8((transformedImg+1)*128),map(lambda c: (c+EPoint(1,1))*Sample.SIDE/2,transformedGrid)).show()
			yield (transformedImg,label)


def loadDataset(root):
	testRatio=0.1
	trainRatio=1-testRatio
	images=[]
	labels=[]
	for d in traverseDirs(root):
		for (img,label) in harvestDir(d):
			images.append(img)
			labels.append(label)
	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)
	return (
		(np.float32(images[:m]),np.float32(labels[:m])),
		(np.float32(images[m:]),np.float32(labels[m:]))
	)


def show(img,filename="x"):
	cv.imshow(filename,img)
	cv.waitKey(0)
	cv.destroyAllWindows()


if __name__=="__main__":
	((trainImages,trainLabels),(testImages,testLabels))=loadDataset(sys.argv[1])
	np.savez_compressed(
		sys.argv[2],
		trainImages=trainImages,
		trainLabels=trainLabels,
		testImages=testImages,
		testLabels=testLabels
	)