Files
@ 52d1a214c032
Branch filter:
Location: OneEye/src/analyzer/__init__.py - annotation
52d1a214c032
2.1 KiB
text/x-python
refactoring and documenting API
7f6fac7f6d8e 07f3fda1cbd7 3798475f45c1 f9ab2070bd69 3798475f45c1 7f6fac7f6d8e 7f6fac7f6d8e 3798475f45c1 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 3798475f45c1 3798475f45c1 07f3fda1cbd7 3798475f45c1 3798475f45c1 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 6f9ec51a8142 6f9ec51a8142 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 | 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))
|