diff --git a/exp/board_detect.py b/exp/board_detect.py --- a/exp/board_detect.py +++ b/exp/board_detect.py @@ -18,6 +18,7 @@ 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") @@ -88,6 +89,7 @@ class BoardDetector: self._rectW=0 self._rectH=0 + self._rect=None def __call__(self,img,filename): # approximately detect the board @@ -98,6 +100,7 @@ class BoardDetector: rect=img[y1:y2,x1:x2] self._rectW=x2-x1 self._rectH=y2-y1 + self._rect=rect # quantize colors colors=self._sampleColors(rect) @@ -111,9 +114,18 @@ class BoardDetector: 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): @@ -143,10 +155,13 @@ class BoardDetector: 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) @@ -199,6 +214,32 @@ class BoardDetector: 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]