Files
@ 52d1a214c032
Branch filter:
Location: OneEye/src/core.py - annotation
52d1a214c032
2.9 KiB
text/x-python
refactoring and documenting API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | 5fe83c3dfb92 a54daf689665 7f6fac7f6d8e 52d1a214c032 5fe83c3dfb92 52d1a214c032 52d1a214c032 5f4489f36388 5fe83c3dfb92 3798475f45c1 f4097dbb3757 3798475f45c1 b197a19e4afe d5d8fe073c1c 5fe83c3dfb92 7f6fac7f6d8e 7f6fac7f6d8e 5fe83c3dfb92 5fe83c3dfb92 8af597b8f819 8af597b8f819 8af597b8f819 8af597b8f819 f4097dbb3757 b197a19e4afe 5fe83c3dfb92 5f4489f36388 5f4489f36388 d5d8fe073c1c 5fe83c3dfb92 6f9ec51a8142 5fe83c3dfb92 5f4489f36388 8af597b8f819 d5d8fe073c1c d5d8fe073c1c d5d8fe073c1c d5d8fe073c1c d5d8fe073c1c d5d8fe073c1c 5fe83c3dfb92 52d1a214c032 6f9ec51a8142 6f9ec51a8142 6f9ec51a8142 52d1a214c032 5a1d87ee0f8a d5d8fe073c1c 6f9ec51a8142 6f9ec51a8142 52d1a214c032 6f9ec51a8142 d5d8fe073c1c 18d23ce9a53f 6f9ec51a8142 18d23ce9a53f 6f9ec51a8142 6f9ec51a8142 a86d59fab023 a86d59fab023 a86d59fab023 2fcaffe8cb70 9ab11204b0f9 9ab11204b0f9 9ab11204b0f9 9ab11204b0f9 9ab11204b0f9 9ab11204b0f9 b197a19e4afe b197a19e4afe 9ab11204b0f9 2fcaffe8cb70 2fcaffe8cb70 4c1ba49ea859 8af597b8f819 a54daf689665 a54daf689665 a54daf689665 d5d8fe073c1c a54daf689665 d5d8fe073c1c d5d8fe073c1c 8a0de753f06f 5fe83c3dfb92 8af597b8f819 4c1ba49ea859 52d1a214c032 d5d8fe073c1c 18d23ce9a53f 18d23ce9a53f 4c1ba49ea859 8af597b8f819 5fe83c3dfb92 8af597b8f819 5fe83c3dfb92 d5d8fe073c1c d5d8fe073c1c d5d8fe073c1c d5d8fe073c1c d5d8fe073c1c d5d8fe073c1c 8af597b8f819 5fe83c3dfb92 5fe83c3dfb92 5fe83c3dfb92 5fe83c3dfb92 5fe83c3dfb92 5fe83c3dfb92 5fe83c3dfb92 5fe83c3dfb92 5fe83c3dfb92 5fe83c3dfb92 8af597b8f819 8af597b8f819 5fe83c3dfb92 5fe83c3dfb92 5fe83c3dfb92 5fe83c3dfb92 5fe83c3dfb92 5fe83c3dfb92 5fe83c3dfb92 5fe83c3dfb92 5fe83c3dfb92 5fe83c3dfb92 8af597b8f819 8af597b8f819 8af597b8f819 5fe83c3dfb92 | import multiprocessing
import threading
import logging
import PIL
import config as cfg
from util import MsgQueue
from gui import gui
from analyzer import ImageAnalyzer
from analyzer.framecache import FrameCache
from go.core import Go, isLegalPosition
from statebag import StateBag
from video import capVideo
log=logging.getLogger(__name__)
class Core:
def __init__(self):
self.grid=None
self.go=Go()
self.detector=ImageAnalyzer()
self._cache=FrameCache()
self.states=StateBag()
self._ownMessages=MsgQueue(self._handleEvent)
self._guiMessages=MsgQueue()
self._vidMessages=MsgQueue()
self._frame=None
self._guiProc=multiprocessing.Process(name="gui", target=gui, args=(self._guiMessages,self._ownMessages))
self._guiProc.start()
self._vidProc=multiprocessing.Process(
name="video",
target=capVideo,
args=(cfg.misc.video, self._vidMessages,self._ownMessages)
)
self._vidProc.start()
def fetchFrame(self,key):
frame=self._cache.get(key)
if frame is None:
(key,frame)=self._cache.getRelative(10)
self._guiMessages.send("setFrame", (frame.copy(), gui.PREVIEW, key))
def putFrame(self,frame):
self._frame=PIL.Image.fromarray(frame)
k=self._cache.put(self._frame)
self._guiMessages.send("setFrame", (self._frame, gui.RECORDING, k))
self.analyze()
def sendParams(self):
self._guiMessages.send("setParams",(self.detector.params.copy(),))
def setParams(self,params):
self.detector.setParams(params)
def analyze(self):
if self.detector.analyze(self._frame):
if isLegalPosition(self.detector.board):
state=self.states.pushState(self.detector.board)
rec=[]
if state:
rec=state.exportRecord()
log.debug("progressive game record: %s",rec)
self._guiMessages.send("setGameState", (self.detector.board,rec))
self.go.transitionMove(self.detector.board)
log.debug("conservative game record: %s",self.go._record)
else:
log.info("illegal position detected")
def listen(self):
listenerThread=threading.Thread(target=lambda: self._ownMessages.listen())
listenerThread.start()
def joinChildren(self):
self._guiProc.join()
self._vidMessages.send("shutDown")
self._vidProc.join()
self._ownMessages.send("!kill",("core",))
def _handleEvent(self,e):
actions={
"fetchFrame": self.fetchFrame,
"putFrame": self.putFrame,
"fetchParams": self.sendParams,
"setParams": self.setParams
}
(actionName,args,kwargs)=e
return actions[actionName](*args,**kwargs)
if __name__=="__main__":
core=Core()
core.listen()
log.info("OneEye started.")
core.joinChildren()
log.info("Exited correctly.")
"""
core
====
grid
go
imageAnalyzer
gui
===
corners
a) keeps references to important objects and uses them
b) gets and sets all relevant data through method calls with core
GUI
<- addCorner(corner)
-> redrawImgView(img,grid)
<- refreshTresholds(tresB,tresW)
BoardView
-> redrawState(go)
core-gui: just pass messages with relevant data (!! always pass object copies, don't share instances)
"""
|