Changeset - c96bd773ec28
[Not reviewed]
default
0 2 1
Laman - 6 years ago 2019-05-03 18:09:55

random image transformations
3 files changed with 106 insertions and 20 deletions:
0 comments (0 inline, 0 general)
exp/keras/prepare_data.py
Show inline comments
 
import os
 
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:
 
		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)
 
		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"):
 
	cv.imshow(filename,img)
 
	cv.waitKey(0)
 
	cv.destroyAllWindows()
 

	
 

	
 
if __name__=="__main__":
 
	root=sys.argv[1]
 
	for d in traverseDirs(root):
 
		harvestDir(d)
exp/keras/transformation_matrices.py
Show inline comments
 
new file 100644
 
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]
 
	])
src/analyzer/corners.py
Show inline comments
 
import logging
 

	
 
from .epoint import EPoint
 

	
 
log=logging.getLogger(__name__)
 

	
 

	
 
class Corners:
 
	def __init__(self,cornerList=[]):
 
		self._corners=cornerList[:]
 
		self._corners=list(cornerList)
 
		self._is_canon=False
 
		self._canonizeOrder()
 

	
 
	## Adds a new corner if there are less than four, replaces the closest otherwise.
 
	def add(self,x,y):
 
		a=EPoint(x,y)
 
		# for i,c in enumerate(self.corners): # move an improperly placed point
 
			# if a.dist(c)<20:
 
				# self.corners[i]=a
 
				# return
 

	
 
		if len(self._corners)<4: # add a new corner
0 comments (0 inline, 0 general)