Changeset - 9433c7ab2989
[Not reviewed]
default
0 2 0
Laman - 6 years ago 2019-02-13 11:08:35

combined lines and stones Hough transform, ignoring stones convexity
2 files changed with 15 insertions and 9 deletions:
0 comments (0 inline, 0 general)
exp/board_detect.py
Show inline comments
 
@@ -53,15 +53,15 @@ def filterStones(contours,bwImg,stoneDim
 
		if w>stoneDims[0] or h>stoneDims[1]*1.5 or w<2 or h<2:
 
			cv.drawMarker(contourImg,tuple(map(int,center)),(0,0,255),cv.MARKER_TILTED_CROSS,12)
 
			keep=False
 
		coverage1=area/(w*h or 1)
 
		hull=cv.convexHull(c)
 
		coverage2=area/(cv.contourArea(hull) or 1)
 
		if coverage2<0.8:
 
			cv.drawMarker(contourImg,tuple(map(int,center)),(0,127,255),cv.MARKER_DIAMOND,12)
 
			keep=False
 
		# if coverage2<0.8:
 
		# 	cv.drawMarker(contourImg,tuple(map(int,center)),(0,127,255),cv.MARKER_DIAMOND,12)
 
		# 	keep=False
 
		if keep:
 
			res.append((EPoint(*center),c))
 
			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,"accepted and rejected stones")
 
@@ -114,20 +114,18 @@ class BoardDetector:
 
		# detect black and white stones
 
		stones=self._detectStones(quantized,colors)
 

	
 
		# 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.update(stonesImg,5)
 
		hough.extract()
 

	
 
		# # detect lines passing through the stones
 
		# lines=self._constructLines(stones)
 
		#
 
		# # detect vanishing points of the lines
exp/hough.py
Show inline comments
 
@@ -24,20 +24,22 @@ class HoughTransform:
 
		self._acc=np.zeros((180,self._diagLen),dtype=np.int32)
 

	
 
		self.update(img)
 

	
 
	def extract(self):
 
		shift=self._diagLen//2
 
		peaks=sorted(list(findPeaks(self._acc)),key=lambda rc: self._acc[rc],reverse=True)[:2*19]
 
		allPeaks=sorted(list(findPeaks(self._acc)),key=lambda rc: self._acc[rc],reverse=True)
 
		peaks=allPeaks[:38]
 
		peaks=[(alpha,d-shift) for (alpha,d) in peaks]
 
		peaks=self._filterClose(peaks)
 
		peaks.sort(key=lambda rc: rc[0])
 
		log.debug("detected peaks: %s",peaks)
 
		(alpha,beta)=self._detectDominantAngles(peaks)
 

	
 
		img=self._createImg()
 
		img=self._markPeaks(img,self._filterClose(allPeaks[:38]))
 
		doublePeaks=peaks+[(alpha+180,-d) for (alpha,d) in peaks]
 
		params=self._computeGridParams([(gamma,d+shift) for (gamma,d) in doublePeaks if alpha<=gamma<=alpha+self._angleBandwidth])
 
		self._drawGridCurve(img,params,0)
 
		params=self._computeGridParams([(gamma,d+shift) for (gamma,d) in doublePeaks if beta<=gamma<=beta+self._angleBandwidth])
 
		self._drawGridCurve(img,params,1)
 
		self.show(img)
 
@@ -60,13 +62,13 @@ class HoughTransform:
 
		return round(d)
 

	
 
	def _filterClose(self,peaks): # a naive implementation
 
		"""Discard points with Euclidean distance on the original image lower than 10.
 
		From such pairs keep only the one with a higher value in the accumulator.
 
		This can delete a series of points. If a-b and b-c are close and a>b>c, only a is kept."""
 
		minDist=10
 
		minDist=13
 
		center=EPoint(*self._center)
 
		res=[]
 
		for (alphaDeg,d) in peaks:
 
			alphaRad=alphaDeg*math.pi/180
 
			point=EPoint.fromPolar((alphaRad,d),center)
 
			ctrl=True
 
@@ -90,13 +92,13 @@ class HoughTransform:
 
				k2+=1
 
			histogram.append((angles[k1],k2-k1))
 
			k1+=1
 
		log.debug("angles histogram: %s",histogram)
 
		dominantAngles=sorted(histogram,key=lambda xy: xy[1],reverse=True)
 
		alpha=dominantAngles[0]
 
		dominantAngles=[beta for beta in dominantAngles if 165>abs(alpha[0]-beta[0])>15]
 
		dominantAngles=[beta for beta in dominantAngles if 180-bandwidth>abs(alpha[0]-beta[0])>bandwidth]
 
		beta=dominantAngles[0]
 
		log.debug("dominant angles: %s, %s",alpha,beta)
 
		return (alpha[0],beta[0])
 

	
 
	def _computeGridParams(self,lines):
 
		log.debug("computing grid parameters for: %s",lines)
 
@@ -123,12 +125,18 @@ class HoughTransform:
 
			img[h//2,x]=[255,255,255]
 
		for y in range(0,h,4):
 
			img[y,w//2]=[255,255,255]
 

	
 
		return img
 

	
 
	def _markPeaks(self,img,peaks):
 
		colors=[[255,0,0],[255,255,0],[0,255,0],[0,255,255],[0,0,255]]
 
		for (i,(alpha,d)) in enumerate(peaks[:38]):
 
			cv.drawMarker(img,(d,alpha),colors[i//9],cv.MARKER_TILTED_CROSS)
 
		return img
 

	
 
	def _drawGridCurve(self,img,params,colorKey=0):
 
		colors=[[0,255,255],[255,0,255],[255,255,0]]
 
		color=colors[colorKey]
 
		(a,b,c,d)=params
 
		(h,w)=img.shape[:2]
 
		curve=lambda x: a*x**3+b*x**2+c*x+d
0 comments (0 inline, 0 general)