diff --git a/src/grid.py b/src/grid.py --- a/src/grid.py +++ b/src/grid.py @@ -8,76 +8,64 @@ from epoint import * # # @return transformed point as a numpy.array def transformPoint(point,A): - return (A*numpy.matrix(point).transpose()).getA1() + return (A*numpy.matrix(point).transpose()).getA1() class Grid: - ## Creates a Grid from the provided Corners object. - # - # Finds the vanishing points of the board lines (corner points define perspectively transformed parallel lines). The vanishing points define the image horizon. - # - # The horizon can be used to construct a matrix for affine rectification of the image (restoring parallel lines parallelism). We transform the corner points by this matrix, - # interpolate them to get proper intersections' coordinates and then transform these back to get their placement at the original image. - # - # The result is stored in grid.intersections, a boardSize*boardSize list with [row][column] coordinates. - # - # @param corners a properly initialized Corners object. !! Needs a check for the proper initialization. - def __init__(self,corners): - # ad - # bc - a,b,c,d=[c.toProjective() for c in corners.corners] - - p1=numpy.cross(a,b) - p2=numpy.cross(c,d) - vanish1=numpy.cross(p1,p2) - # !! 32 bit int can overflow. keeping it reasonably small. might want to use a cleaner solution - vanish1=EPoint.fromProjective(vanish1).toProjective() # !! EPoint fails with point in infinity - - p3=numpy.cross(a,d) - p4=numpy.cross(b,c) - vanish2=numpy.cross(p3,p4) - vanish2=EPoint.fromProjective(vanish2).toProjective() - - horizon=numpy.cross(vanish1,vanish2) + ## Creates a Grid from the provided Corners object. + # + # Finds the vanishing points of the board lines (corner points define perspectively transformed parallel lines). The vanishing points define the image horizon. + # + # The horizon can be used to construct a matrix for affine rectification of the image (restoring parallel lines parallelism). We transform the corner points by this matrix, + # interpolate them to get proper intersections' coordinates and then transform these back to get their placement at the original image. + # + # The result is stored in grid.intersections, a boardSize*boardSize list with [row][column] coordinates. + # + # @param corners a properly initialized Corners object. !! Needs a check for the proper initialization. + def __init__(self,corners): + # ad + # bc + a,b,c,d=[c.toProjective() for c in corners.corners] - horizon=EPoint.fromProjective(horizon).toProjective() - - rectiMatrix=numpy.matrix([horizon,[0,1,0],[0,0,1]]) - rectiMatrixInv=numpy.linalg.inv(rectiMatrix) - - - affineCorners=[EPoint.fromProjective(transformPoint(x,rectiMatrix)) for x in (a,b,c,d)] - x=[affineCorners[0]-affineCorners[3],affineCorners[1]-affineCorners[2],affineCorners[0]-affineCorners[1],affineCorners[3]-affineCorners[2]] - - self.intersections=[] - boardSize=19 - for r in range(boardSize): - self.intersections.append([None]*boardSize) - rowStart=(affineCorners[0]*(boardSize-1-r)+affineCorners[1]*r) / (boardSize-1) - rowEnd=(affineCorners[3]*(boardSize-1-r)+affineCorners[2]*r) / (boardSize-1) - - for c in range(boardSize): - affineIntersection=(rowStart*(boardSize-1-c)+rowEnd*c) / (boardSize-1) - self.intersections[r][c]=EPoint.fromProjective(transformPoint(affineIntersection.toProjective(),rectiMatrixInv)) + p1=numpy.cross(a,b) + p2=numpy.cross(c,d) + vanish1=numpy.cross(p1,p2) + # !! 32 bit int can overflow. keeping it reasonably small. might want to use a cleaner solution + vanish1=EPoint.fromProjective(vanish1).toProjective() # !! EPoint fails with point in infinity - def stoneSizeAt(self,r,c,sizeCoef): - intersection=self.intersections[r][c] + p3=numpy.cross(a,d) + p4=numpy.cross(b,c) + vanish2=numpy.cross(p3,p4) + vanish2=EPoint.fromProjective(vanish2).toProjective() - if c>0: width=sizeCoef*(intersection.x-self.intersections[r][c-1].x) - else: width=sizeCoef*(self.intersections[r][c+1].x-intersection.x) - if r>0: height=sizeCoef*(intersection.y-self.intersections[r-1][c].y) - else: height=sizeCoef*(self.intersections[r+1][c].y-intersection.y) + horizon=numpy.cross(vanish1,vanish2) - return (width,height) + horizon=EPoint.fromProjective(horizon).toProjective() + + rectiMatrix=numpy.matrix([horizon,[0,1,0],[0,0,1]]) + rectiMatrixInv=numpy.linalg.inv(rectiMatrix) -# from corners import Corners -# corn=Corners() + affineCorners=[EPoint.fromProjective(transformPoint(x,rectiMatrix)) for x in (a,b,c,d)] + x=[affineCorners[0]-affineCorners[3],affineCorners[1]-affineCorners[2],affineCorners[0]-affineCorners[1],affineCorners[3]-affineCorners[2]] + + self.intersections=[] + boardSize=19 + for r in range(boardSize): + self.intersections.append([None]*boardSize) + rowStart=(affineCorners[0]*(boardSize-1-r)+affineCorners[1]*r) / (boardSize-1) + rowEnd=(affineCorners[3]*(boardSize-1-r)+affineCorners[2]*r) / (boardSize-1) -# corn.add(106,86) -# corn.add(57,321) -# corn.add(416,320) -# corn.add(365,86) -# corn.add(365,88) + for c in range(boardSize): + affineIntersection=(rowStart*(boardSize-1-c)+rowEnd*c) / (boardSize-1) + self.intersections[r][c]=EPoint.fromProjective(transformPoint(affineIntersection.toProjective(),rectiMatrixInv)) + + def stoneSizeAt(self,r,c,sizeCoef): + intersection=self.intersections[r][c] -# x=Grid(corn) + if c>0: width=sizeCoef*(intersection.x-self.intersections[r][c-1].x) + else: width=sizeCoef*(self.intersections[r][c+1].x-intersection.x) + if r>0: height=sizeCoef*(intersection.y-self.intersections[r-1][c].y) + else: height=sizeCoef*(self.intersections[r+1][c].y-intersection.y) + + return (width,height)