diff --git a/exp/board_detect.py b/exp/board_detect.py --- a/exp/board_detect.py +++ b/exp/board_detect.py @@ -16,7 +16,7 @@ import scipy.signal from geometry import Line, point2lineDistance from polar_hough import PolarHough from annotations import DataFile,computeBoundingBox -from hough import show +from hough import show,prepareEdgeImg,HoughTransform from analyzer.epoint import EPoint from analyzer.corners import Corners @@ -64,13 +64,13 @@ def filterStones(contours,bwImg,stoneDim cv.drawMarker(contourImg,tuple(map(int,center)),(255,0,0),cv.MARKER_CROSS) log.debug("accepted: %s",len(res)) log.debug("rejected: %s",len(contours)-len(res)) - show(contourImg) + show(contourImg,"accepted and rejected stones") return res def groupLines(points,minCount,tolerance): random.shuffle(points) - sample=points[:57] + sample=points[:] for (i,a) in enumerate(sample): for (j,b) in enumerate(sample): if j<=i: continue @@ -110,23 +110,36 @@ class BoardDetector: # detect black and white stones stones=self._detectStones(quantized,colors) - # detect lines passing through the stones - lines=self._constructLines(stones) + # detect lines from edges and stones + edgeImg=prepareEdgeImg(rect) + hough=HoughTransform(edgeImg) + hough.extract() + stonesImg=np.zeros((self._rectH,self._rectW),np.uint8) + for (point,c) in stones: + cv.circle(stonesImg,(int(point.x),int(point.y)),2,255,-1) + # cv.drawContours(stonesImg,[c for (point,c) in stones],-1,255,-1) + show(stonesImg,"detected stones") + # hough.update(stonesImg,5) + hough=HoughTransform(stonesImg) + hough.extract() - # detect vanishing points of the lines - 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 + # # detect lines passing through the stones + # lines=self._constructLines(stones) + # + # # detect vanishing points of the lines + # imgCenter=EPoint(w//2-x1, h//2-y1) + # (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)) + # vanish=self._detectVanishingPoints(lines,imgCenter,(v1.toPolar(imgCenter),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] @@ -158,20 +171,22 @@ class BoardDetector: maskB=cv.erode(maskB,kernel,iterations=3) # distTransform = cv.distanceTransform(maskB,cv.DIST_L2,5) # maskB=cv.inRange(distTransform,6,10) - show(maskB) + show(maskB,"black areas") maskW=cv.inRange(quantized,colors[1]-unit,colors[1]+unit) maskW=cv.morphologyEx(maskW,cv.MORPH_OPEN,kernel,iterations=1) maskW=cv.erode(maskW,kernel,iterations=2) - show(maskW) + show(maskW,"white areas") stones=cv.bitwise_or(maskB,maskW) - show(stones) + show(stones,"black and white areas") return stones def _constructLines(self,stoneLocs): lineDict=dict() - minCount=min(max(math.sqrt(len(stoneLocs))-4,3),7) + # minCount=min(max(math.sqrt(len(stoneLocs))-4,3),7) + minCount=6 log.debug("min count: %s",minCount) - for line in groupLines([point for (point,contour) in stoneLocs],minCount,2): + points=[point for (point,contour) in stoneLocs] + for line in groupLines(points,minCount,2): key=line.getSortedPoints() if key in lineDict: # we already have a line with the same incident points continue @@ -193,6 +208,7 @@ class BoardDetector: cv.drawContours(linesImg,[c for (point,c) in stoneLocs],-1,(255,255,255),-1) for (p,c) in stoneLocs: cv.drawMarker(linesImg,(int(p.x),int(p.y)),(255,0,0),cv.MARKER_CROSS) + self._printLines(lines,points,linesImg) for line in lines: points=line.getSortedPoints() (xa,ya)=points[0] @@ -202,15 +218,28 @@ class BoardDetector: return lines - def _detectVanishingPoints(self,lines,imgCenter): + def _printLines(self,lines,allPoints,img): + for (i,line) in enumerate(lines): + img_=np.copy(img) + points=list(line.getSortedPoints()) + (a,b)=max(((a,b) for a in points for b in points if a %s",point,point.toPolar(imgCenter)) + # log.debug("%s -> %s",point,point.toPolar(imgCenter)) polarHough.put(point.toPolar(imgCenter)) - vanish=[EPoint.fromPolar(p,imgCenter) for p in polarHough.extract(2)] + vanish=[EPoint.fromPolar(p,imgCenter) for p in polarHough.extract(2,trueVs)] log.debug(vanish) return vanish