# HG changeset patch # User Laman # Date 2018-12-12 22:38:32 # Node ID 52d1a214c0323390202113f09cfc4eecfc5b60ad # Parent 6f9ec51a8142ab937e53672a18092a242e09370a refactoring and documenting API diff --git a/overview.md b/overview.md new file mode 100644 --- /dev/null +++ b/overview.md @@ -0,0 +1,22 @@ +Processes and threads +===================== + +Processes communicate through MsgQueues (a wrapper around multiprocessing.Queue). Each owns one incoming and holds any number of outcoming queues. The queue runs in one thread, reads messages and calls handlers on its owner. + +Core +---- +* Main process, starts GUI and VideoCapture. Waits for them to finish. +* Runs ImageAnalyzer and StateBag. +* Messages API: + * putFrame(frame) + * setParams(params) + * fetchFrame(key) + * fetchParams(params) + +GUI +--- +* Presents data for the user, handles user input. + +VideoCapture +------------ +* Consumes a video stream, sending captured frames to Core. \ No newline at end of file diff --git a/project.md b/project.md deleted file mode 100755 --- a/project.md +++ /dev/null @@ -1,35 +0,0 @@ -OneEye -====== - -Program to extract moves of a go game from video and save them or broadcast online. - -Modules: - - Video: grabbing still frames from a video file / stream. Using FFmpeg. - - Graphic: extracting game position from an image. Using Pillow. - - Watcher: interpreting sequence of game positions as a sequence of moves. - - Broadcaster: interfacing with a go server. - - -Graphic -------- -Interpolating the board grid from specified corner points. Using vanishing points and horizon in projective geometry. - -Determining the point status based on majority voting of pixels in its neighbourhood (deciding by HSI intensity). - -Autodetection of the board? - - -Watcher -------- -Base case: we have two correctly recognized positions differing by a single move (single added stone). Easy. - -Issues: - - illegal positions -> ignorable - - positions unreachable from the previous state - - reachable from any past state. (Incorrect states inbetween). How to pick the correct leaf of such a tree? - - reachable by more than one move. Issues with branching factor. - - board shifts -> repaired manually (or automatically), further positions have to be reevaluated - - stone shifts - - stone stops being recognized -> fixable manually and even ignorable - - stone is recognized at an empty intersection. It can be occupied later for real. What do? - diff --git a/src/core.py b/src/core.py --- a/src/core.py +++ b/src/core.py @@ -1,7 +1,10 @@ import multiprocessing import threading import logging + import PIL + +import config as cfg from util import MsgQueue from gui import gui from analyzer import ImageAnalyzer @@ -9,7 +12,6 @@ from analyzer.framecache import FrameCac from go.core import Go, isLegalPosition from statebag import StateBag from video import capVideo -import config as cfg log=logging.getLogger(__name__) @@ -37,16 +39,16 @@ class Core: ) self._vidProc.start() - def showFrame(self,key): + def fetchFrame(self,key): frame=self._cache.get(key) if frame is None: (key,frame)=self._cache.getRelative(10) - self._guiMessages.send("setCurrentFrame", (frame.copy(), gui.PREVIEW, key)) + 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("setCurrentFrame", (self._frame, gui.RECORDING, k)) + self._guiMessages.send("setFrame", (self._frame, gui.RECORDING, k)) self.analyze() def sendParams(self): @@ -82,8 +84,7 @@ class Core: def _handleEvent(self,e): actions={ - "prevFrame": lambda: self.relativeFrame(-1), - "nextFrame": lambda: self.relativeFrame(1), + "fetchFrame": self.fetchFrame, "putFrame": self.putFrame, "fetchParams": self.sendParams, "setParams": self.setParams diff --git a/src/gui/__init__.py b/src/gui/__init__.py --- a/src/gui/__init__.py +++ b/src/gui/__init__.py @@ -72,7 +72,7 @@ class GUI: def _handleEvent(self,e): actions={ - "setCurrentFrame": self._frameHandler, + "setFrame": self._frameHandler, "setGameState": self._stateHandler, "setParams": self._paramsHandler } @@ -80,12 +80,12 @@ class GUI: return actions[actionName](*args,**kwargs) - def _frameHandler(self,newFrame,type,key): + def _frameHandler(self,frame,type,key): if self._state!=type and self.mainWindow.imgView.isSet(): - log.info("ignored setCurrentFrame event, wrong type") + log.info("ignored setFrame event, wrong type") return self._frameKey=key - self.mainWindow.setCurrentFrame(newFrame) + self.mainWindow.setFrame(frame) self.root.event_generate("<>") def _stateHandler(self,gameState,moves): diff --git a/src/gui/mainwindow.py b/src/gui/mainwindow.py --- a/src/gui/mainwindow.py +++ b/src/gui/mainwindow.py @@ -16,7 +16,7 @@ class MainWindow(tk.Frame,MsgMixin): self.grid(column=0,row=0,sticky=(N,S,E,W)) self._createWidgets() - def setCurrentFrame(self,frame): + def setFrame(self,frame): self.imgView.setImg(frame) def _createWidgets(self):