Changeset - c3345c5afb6d
[Not reviewed]
default
0 2 0
Laman - 6 years ago 2019-02-22 13:01:54

more robust color handling
2 files changed with 29 insertions and 20 deletions:
0 comments (0 inline, 0 general)
exp/board_detect.py
Show inline comments
 
@@ -26,11 +26,16 @@ log.basicConfig(level=log.DEBUG,format="
 

	
 
def kmeans(img):
 
	arr=np.reshape(img,(-1,3)).astype(np.float)
 
	colors=np.array([[0,0,0],[255,255,255],[193,165,116]],np.float)
 
	log.debug(colors)
 
	(centers,distortion)=scipy.cluster.vq.kmeans(arr,colors)
 
	wood=[193,165,116]
 
	(centers,distortion)=scipy.cluster.vq.kmeans(arr,3)
 
	log.debug("k-means centers: %s",centers)
 
	return centers
 
	(black,empty,white)=sorted(centers,key=sum)
 
	if np.linalg.norm(black)>np.linalg.norm(black-wood):
 
		black=None
 
	if np.linalg.norm(white-[255,255,255])>np.linalg.norm(white-wood):
 
		white=None
 
	log.debug("black, white: %s, %s",black,white)
 
	return (black,white,centers)
 

	
 

	
 
def quantize(img,centers):
 
@@ -103,7 +108,7 @@ class BoardDetector:
 
		self._rect=rect
 

	
 
		# quantize colors
 
		colors=self._sampleColors(rect)
 
		(black,white,colors)=self._sampleColors(rect)
 
		quantized=quantize(rect,colors)
 
		gray=cv.cvtColor(rect,cv.COLOR_BGR2GRAY)
 
		edges=cv.Canny(gray,70,130)
 
@@ -112,7 +117,7 @@ class BoardDetector:
 
		show(quantized,"quantized, edges separated")
 

	
 
		# detect black and white stones
 
		stones=self._detectStones(quantized,colors)
 
		stones=self._detectStones(quantized,black,white)
 

	
 
		# detect lines from edges and stones
 
		edgeImg=prepareEdgeImg(rect)
 
@@ -122,7 +127,7 @@ class BoardDetector:
 
			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,3)
 
		hough.update(stonesImg,5)
 
		hough.extract()
 

	
 
		# # detect lines passing through the stones
 
@@ -154,9 +159,9 @@ class BoardDetector:
 
		minirect=rect[h//4:3*h//4, w//4:3*w//4]
 
		return kmeans(minirect)
 

	
 
	def _detectStones(self,quantized,colors):
 
	def _detectStones(self,quantized,black,white):
 
		(h,w)=quantized.shape[:2]
 
		mask=self._maskStones(quantized,colors)
 
		mask=self._maskStones(quantized,black,white)
 
		stoneDims=(w/19,h/19)
 
		log.debug("stone dims: %s - %s",tuple(x/2 for x in stoneDims),stoneDims)
 

	
 
@@ -165,19 +170,23 @@ class BoardDetector:
 

	
 
		return stoneLocs
 

	
 
	def _maskStones(self,quantized,colors):
 
	def _maskStones(self,quantized,black,white):
 
		unit=np.array([1,1,1],dtype=np.uint8)
 
		maskB=cv.inRange(quantized,colors[0]-unit,colors[0]+unit)
 
		if black is not None:
 
			maskB=cv.inRange(quantized,black-unit,black+unit)
 

	
 
		distTransform=cv.distanceTransform(maskB,cv.DIST_L2,5)
 
		maskB=cv.inRange(distTransform,6,20)
 
		show(maskB,"black areas")
 
			distTransform=cv.distanceTransform(maskB,cv.DIST_L2,5)
 
			maskB=cv.inRange(distTransform,6,20)
 
			show(maskB,"black areas")
 
		else: maskB=np.zeros(quantized.shape[:2],dtype=np.uint8)
 

	
 
		maskW=cv.inRange(quantized,colors[1]-unit,colors[1]+unit)
 
		distTransform=cv.distanceTransform(maskW,cv.DIST_L2,5)
 
		maskW=cv.inRange(distTransform,6,20)
 
		if white is not None:
 
			maskW=cv.inRange(quantized,white-unit,white+unit)
 
			distTransform=cv.distanceTransform(maskW,cv.DIST_L2,5)
 
			maskW=cv.inRange(distTransform,6,20)
 
			show(maskW,"white areas")
 
		else: maskW=np.zeros(quantized.shape[:2],dtype=np.uint8)
 

	
 
		show(maskW,"white areas")
 
		stones=cv.bitwise_or(maskB,maskW)
 
		show(stones,"black and white areas")
 
		return stones
exp/hough.py
Show inline comments
 
@@ -115,8 +115,8 @@ class HoughTransform:
 

	
 
	def _detectLines(self):
 
		bag=LineBag()
 
		for alpha in range(0,180,3):
 
			for beta in range(min(alpha-60,0),alpha+60,3):
 
		for alpha in range(0,180,2):
 
			for beta in range(max(alpha-60,0),alpha+60,2):
 
				accLine=[self._acc[key] for key in self._readLineKeys(alpha,beta)]
 
				(peaks,props)=scipy.signal.find_peaks(accLine,prominence=0)
 
				(prominences,peaks)=zip(*sorted(zip(props["prominences"],peaks),reverse=True)[:19])
0 comments (0 inline, 0 general)