diff --git a/exp/keras/prepare_data.py b/exp/keras/prepare_data.py --- a/exp/keras/prepare_data.py +++ b/exp/keras/prepare_data.py @@ -3,14 +3,60 @@ import sys import re import random +import numpy as np import cv2 as cv sys.path.append("../exp") -from annotations import DataFile,computeBoundingBox +from annotations import DataFile,computeBoundingBox,Corners +from geometry import Line +from keras.transformation_matrices import getIdentity,getRotation,getTranslation,getScale,getMirroring,getProjection random.seed(361) +class Sample: + SIDE=256 + + def __init__(self,img,grid): + self.img=img + self.grid=grid + + def transform(self): + 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)) + grid=Corners(c.transform(m) for c in self.grid) + Sample(img,grid).show() + + 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=np.copy(self.img) + 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: @@ -31,24 +77,8 @@ def harvestDir(path): for f in files: img=cv.imread(f.path) for b in boards: - crop(img,b) - - -def crop(img,board): - margin=0.2 - (hi,wi)=img.shape[:2] - (x1,y1,x2,y2)=computeBoundingBox(board.board) - (wb,hb)=(x2-x1,y2-y1) - dx1=min(int(wb*margin),x1) - dx2=min(int(wb*margin),wi-x2) - dy1=min(int(hb*margin),y1) - dy2=min(int(hb*margin),hi-y2) - xa=x1-random.randint(0,dx1) - xb=x2+random.randint(0,dx2) - ya=y1-random.randint(0,dy1) - yb=y2+random.randint(0,dy2) - show(img[ya:yb,xa:xb]) - return img[ya:yb,xa:xb] + sample=Sample(img,b.grid) + sample.transform() def show(img,filename="x"): diff --git a/exp/keras/transformation_matrices.py b/exp/keras/transformation_matrices.py new file mode 100644 --- /dev/null +++ b/exp/keras/transformation_matrices.py @@ -0,0 +1,56 @@ +import math +import random + +import numpy as np + + +def getIdentity(): + return np.float32([ + [1,0,0], + [0,1,0], + [0,0,1] + ]) + + +def getRotation(): + alpha=random.random()*2*math.pi + return np.float32([ + [math.cos(alpha),math.sin(alpha),0], + [-math.sin(alpha),math.cos(alpha),0], + [0,0,1] + ]) + + +def getTranslation(dx,dy): + return np.float32([ + [1,0,dx], + [0,1,dy], + [0,0,1] + ]) + + +def getScale(kx,ky=0): + if not ky: ky=kx + return np.float32([ + [kx,0,0], + [0,ky,0], + [0,0,1] + ]) + + +def getMirroring(): + return np.float32([ + [random.choice((1,-1)),0,0], + [0,1,0], + [0,0,1] + ]) + + +def getProjection(): + dx=random.uniform(-0.001,0.001) + dy=random.uniform(-0.001,0.001) + return np.float32([ + [1,0,0], + [0,1,0], + [dx,dy,1] + ]) diff --git a/src/analyzer/corners.py b/src/analyzer/corners.py --- a/src/analyzer/corners.py +++ b/src/analyzer/corners.py @@ -7,7 +7,7 @@ log=logging.getLogger(__name__) class Corners: def __init__(self,cornerList=[]): - self._corners=cornerList[:] + self._corners=list(cornerList) self._is_canon=False self._canonizeOrder()