Changeset - 7df1503a4ca6
[Not reviewed]
default
0 1 0
Laman - 6 years ago 2019-01-25 20:05:40

computing transformation matrix
1 file changed with 44 insertions and 3 deletions:
0 comments (0 inline, 0 general)
exp/board_detect.py
Show inline comments
 
@@ -15,12 +15,13 @@ import scipy.signal
 

	
 
from geometry import Line, point2lineDistance
 
from polar_hough import PolarHough
 
from annotations import DataFile,computeBoundingBox
 
from hough import show
 
from analyzer.epoint import EPoint
 
from analyzer.corners import Corners
 

	
 
random.seed(361)
 
log.basicConfig(level=log.DEBUG,format="%(message)s")
 

	
 

	
 
def kmeans(img):
 
@@ -85,22 +86,24 @@ def groupLines(points,minCount,tolerance
 
class BoardDetector:
 
	def __init__(self,annotationsPath):
 
		self._annotations=DataFile(annotationsPath)
 

	
 
		self._rectW=0
 
		self._rectH=0
 
		self._rect=None
 

	
 
	def __call__(self,img,filename):
 
		# approximately detect the board
 
		(h,w)=img.shape[:2]
 
		log.debug("image dimensions: %s x %s",w,h)
 
		show(img,filename)
 
		(x1,y1,x2,y2)=self._detectRough(img,filename)
 
		rect=img[y1:y2,x1:x2]
 
		self._rectW=x2-x1
 
		self._rectH=y2-y1
 
		self._rect=rect
 

	
 
		# quantize colors
 
		colors=self._sampleColors(rect)
 
		quantized=quantize(rect,colors)
 
		show(quantized,filename)
 

	
 
@@ -108,15 +111,24 @@ class BoardDetector:
 
		stones=self._detectStones(quantized,colors)
 

	
 
		# detect lines passing through the stones
 
		lines=self._constructLines(stones)
 

	
 
		# detect vanishing points of the lines
 
		vanish=self._detectVanishingPoints(lines,EPoint(w//2-x1, h//2-y1))
 
		imgCenter=EPoint(w//2-x1, h//2-y1)
 
		vanish=self._detectVanishingPoints(lines,imgCenter)
 
		(a,b,c,d)=(p-EPoint(x1,y1) for p in self._annotations[filename][0])
 
		(p,q,r,s)=(Line(a,b),Line(b,c),Line(c,d),Line(d,a))
 
		v1=p.intersect(r)
 
		v2=q.intersect(s)
 
		log.debug("true vanishing points: %s ~ %s, %s ~ %s",v1,v1.toPolar(imgCenter),v2,v2.toPolar(imgCenter))
 

	
 
		# rectify the image
 
		matrix=self._computeTransformationMatrix(vanish,lines)
 
		transformed=cv.warpPerspective(rect,matrix,(self._rectW,self._rectH))
 

	
 
		# determine precise board edges
 

	
 
	def _detectRough(self,img,filename):
 
		corners=self._annotations[filename][0]
 
		(x1,y1,x2,y2)=computeBoundingBox(corners)
 
		log.debug("bounding box: (%s,%s) - (%s,%s)",x1,y1,x2,y2)
 
@@ -140,16 +152,19 @@ class BoardDetector:
 

	
 
	def _maskStones(self,quantized,colors):
 
		unit=np.array([1,1,1],dtype=np.uint8)
 
		kernel=np.ones((3,3),np.uint8)
 
		maskB=cv.inRange(quantized,colors[0]-unit,colors[0]+unit)
 
		maskB=cv.morphologyEx(maskB,cv.MORPH_OPEN,kernel,iterations=1)
 
		maskB=cv.erode(maskB,kernel,iterations=4)
 
		maskB=cv.erode(maskB,kernel,iterations=3)
 
		# distTransform = cv.distanceTransform(maskB,cv.DIST_L2,5)
 
		# maskB=cv.inRange(distTransform,6,10)
 
		show(maskB)
 
		maskW=cv.inRange(quantized,colors[1]-unit,colors[1]+unit)
 
		maskW=cv.erode(maskW,kernel,iterations=3)
 
		maskW=cv.morphologyEx(maskW,cv.MORPH_OPEN,kernel,iterations=1)
 
		maskW=cv.erode(maskW,kernel,iterations=2)
 
		show(maskW)
 
		stones=cv.bitwise_or(maskB,maskW)
 
		show(stones)
 
		return stones
 

	
 
	def _constructLines(self,stoneLocs):
 
@@ -196,12 +211,38 @@ class BoardDetector:
 
				log.debug("%s -> %s",point,point.toPolar(imgCenter))
 
				polarHough.put(point.toPolar(imgCenter))
 
		vanish=[EPoint.fromPolar(p,imgCenter) for p in polarHough.extract(2)]
 
		log.debug(vanish)
 
		return vanish
 

	
 
	def _computeTransformationMatrix(self,vanish,lines):
 
		(v1,v2)=vanish
 
		(p,r)=sorted(lines,key=lambda p: point2lineDistance(p.a,p.b,v1))[:2]
 
		(q,s)=sorted(lines,key=lambda p: point2lineDistance(p.a,p.b,v2))[:2]
 
		(a,b,c,d)=Corners([p.intersect(q),q.intersect(r),r.intersect(s),s.intersect(p)]) # canonize the abcd order
 
		a_=EPoint(b.x,min(a.y,d.y))
 
		b_=EPoint(b.x,max(b.y,c.y))
 
		c_=EPoint(c.x,max(b.y,c.y))
 
		d_=EPoint(c.x,min(a.y,d.y))
 
		abcd=[list(point) for point in (a,b,c,d)]
 
		abcd_=[list(point) for point in (a_,b_,c_,d_)]
 
		log.debug("abcd: %s ->",(a,b,c,d))
 
		log.debug("-> abcd_: %s",(a_,b_,c_,d_))
 
		matrix=cv.getPerspectiveTransform(np.float32(abcd),np.float32(abcd_))
 
		log.debug("transformation matrix: %s",matrix)
 

	
 
		rect=np.copy(self._rect)
 
		for point in (a,b,c,d):
 
			cv.drawMarker(rect,(int(point.x),int(point.y)),(0,255,255),cv.MARKER_TILTED_CROSS)
 
		show(rect)
 
		transformed=cv.warpPerspective(rect,matrix,(self._rectW,self._rectH))
 
		show(transformed)
 

	
 
		return matrix
 

	
 

	
 
if __name__=="__main__":
 
	detector=BoardDetector(sys.argv[2])
 
	filepath=sys.argv[1]
 
	filename=os.path.basename(filepath)
 
	img=cv.imread(filepath)
 
	detector(img,filename)
0 comments (0 inline, 0 general)