Files @ 7cb01d4080c9
Branch filter:

Location: OneEye/src/analyzer/__init__.py - annotation

Laman
a hinted neural network (failed)
import logging

from .grid import Grid
from util import BLACK,WHITE,EMPTY, exportBoard

log=logging.getLogger(__name__)


class Params:
	def __init__(self):
		self.tresB=30
		self.tresW=60
		self.corners=[]

	def copy(self):
		res=Params()
		res.tresB=self.tresB
		res.tresW=self.tresW
		res.corners=[p*1 for p in self.corners] # *1 forces copy
		return res


class ImageAnalyzer:
	def __init__(self,tresB=30,tresW=60):
		self.board=[[EMPTY]*19 for r in range(19)]
		self.grid=None

		self.params=Params()
		self.params.tresB=tresB
		self.params.tresW=tresW

	# let's not concern ourselves with sizecoef and shift here anymore. we want corners to come already properly recomputed
	def analyze(self,image):
		if self.grid==None:
			log.info("ImageAnalyzer.analyze() aborted: no grid available.")
			return False

		for r in range(19):
			for c in range(19):
				intersection=self.grid.intersections[r][c]

				self.board[r][c]=self.analyzePoint(image,r,c,intersection,*(self.grid.stoneSizeAt(r,c)))

		log.info("board analyzed:\n%s", exportBoard(self.board))
		return True

	def analyzePoint(self,image,row,col,imageCoords,stoneWidth,stoneHeight):
		b=w=e=0

		((x1,y1),(x2,y2))=relevantRect(imageCoords,stoneWidth,stoneHeight)

		for y in range(y1,y2+1):
			for x in range(x1,x2+1):
				try:
					red,green,blue=image.getpixel((x,y))
				except IndexError: continue

				I=(red+green+blue)/255/3
				m=min(red,green,blue)
				S=1-m/I if I!=0 else 0
				if 100*I<self.params.tresB: b+=1
				elif 100*I>self.params.tresW: w+=1
				else: e+=1

		log.debug("(%d,%d) ... (b=%d,w=%d,e=%d)", row, col, b, w, e)

		if b>=w and b>=e: return BLACK
		if w>=b and w>=e: return WHITE
		return EMPTY

	def setParams(self,params):
		self.params=params.copy()
		if len(params.corners)==4:
			self.grid=Grid(self.params.corners)

	def setCorners(self,corners):
		self.params.corners=[p*1 for p in corners]
		self.grid=Grid(corners)


def relevantRect(imageCoords,stoneWidth,stoneHeight):
	x=int(imageCoords.x)
	y=int(imageCoords.y)
	xmax=max(int(stoneWidth*2//7), 2) # !! optimal parameters subject to further research
	ymax=max(int(stoneHeight*2//7), 2)

	return ((x-xmax,y-ymax), (x+xmax,y+ymax))