Changeset - 9ef2a632d9b0
[Not reviewed]
default
0 0 5
Laman - 10 years ago 2015-03-04 23:02:20

init commit
5 files changed with 196 insertions and 0 deletions:
0 comments (0 inline, 0 general)
.hgignore
Show inline comments
 
new file 100644
 
^images/
 
\ No newline at end of file
grid.py
Show inline comments
 
new file 100644
 
class Grid:
 
  pass
 
\ No newline at end of file
gui.py
Show inline comments
 
new file 100644
 
import tkinter as tk
 
from PIL import ImageTk
 
import PIL
 
import math
 
 
class EPoint:
 
  def __init__(self,x,y):
 
    self.x=x
 
    self.y=y
 
  
 
  def dist(self,a):
 
    return math.sqrt((self.x-a.x)**2+(self.y-a.y)**2)
 
 
class Application(tk.Frame):
 
  def __init__(self, master=None):
 
    self.corners=[]
 
    
 
    tk.Frame.__init__(self, master)
 
    self.pack()
 
    self.createWidgets()
 
 
  def createWidgets(self):
 
    self.hi_there = tk.Button(self)
 
    self.hi_there["text"] = "Hello World\n(click me)"
 
    self.hi_there["command"] = self.say_hi
 
    self.hi_there.pack(side="top")
 
    
 
    self.canvas=tk.Canvas(self)
 
    self.canvas.configure(width=480,height=360,background="#ff4444")
 
    imgOrig=PIL.Image.open("images/1.jpg")
 
    self.img=ImageTk.PhotoImage(imgOrig.resize((int(self.canvas['width']),int(self.canvas['height'])),resample=PIL.Image.BILINEAR))
 
    
 
    self.canvas.bind('<1>',lambda e: self.addCorner(e.x,e.y))
 
    self.canvas.create_image(2,2,anchor="nw",image=self.img)
 
    self.canvas.create_line(30,30,40,40,fill="#00ff00")
 
    self.canvas.create_line(30,40,40,30,fill="#00ff00")
 
    
 
    self.canvas.pack()
 
 
    self.QUIT = tk.Button(self, text="QUIT", fg="red", command=root.destroy)
 
    self.QUIT.pack(side="bottom")
 
 
  def say_hi(self):
 
    print("hi there, everyone!")
 
    
 
  def addCorner(self,x,y):
 
    a=EPoint(x,y)
 
    for i,c in enumerate(self.corners): # move an improperly placed point
 
      if a.dist(c)<20:
 
        self.corners[i]=a
 
        return
 
    
 
    if len(self.corners)<4: # add a new corner
 
      self.corners.append(a)
 
      return
 
    
 
    index,minDist=0,float('inf') # replace the corner closest to the clicked point
 
    for i,c in enumerate(self.corners):
 
      if a.dist(c)<minDist:
 
        index,minDist=i,a.dist(c)
 
    
 
    self.corners[index]=a
 
    
 
  def redrawGrid(self):
 
    pass
 
 
root = tk.Tk()
 
app = Application(master=root)
 
app.mainloop()
project.md
Show inline comments
 
new file 100644
 
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?
 
vector3.py
Show inline comments
 
new file 100644
 
import math
 
 
 
class Vector3:
 
 
  def __init__(self,x,y,z):
 
    self.x=x
 
    self.y=y
 
    self.z=z
 
    
 
  def __add__(self,v):
 
    return Vector3(self.x+v.x, self.y+v.y, self.z+v.z)
 
    
 
  def __iadd__(self,v):
 
    self.x+=v.x
 
    self.y+=v.y
 
    self.z+=v.z
 
    return self
 
    
 
  def __sub__(self,v):
 
    return Vector3(self.x-v.x, self.y-v.y, self.z-v.z)
 
    
 
  def __isub__(self,v):
 
    self.x-=v.x
 
    self.y-=v.y
 
    self.z-=v.z
 
    return self
 
    
 
  def __neg__(self):
 
    return Vector3(-self.x, -self.y, -self.z)
 
  
 
  def __mul__(self,a): # scalar or dot product
 
    if isinstance(a,Vector3):
 
      return self.x*a.x + self.y*a.y + self.z*a.z
 
    else:
 
      return Vector3(self.x*a, self.y*a, self.z*a)
 
    
 
  def __imul__(self,a):
 
    if isinstance(a,Vector3): raise BadOperandError(self,a,'attempted in-place dot multiplication')
 
    self.x*=a
 
    self.y*=a
 
    self.z*=a
 
    return self
 
    
 
  def __rmul__(self,a):
 
    return self.__mul__(a)
 
    
 
  def __truediv__(self,a):
 
    return Vector3(self.x/a, self.y/a, self.z/a)
 
    
 
  def __itruediv__(self,a):
 
    self.x/=a
 
    self.y/=a
 
    self.z/=a
 
    return self
 
  
 
  def __floordiv__(self,a):
 
    return Vector3(self.x//a, self.y//a, self.z//a)
 
    
 
  def __ifloordiv__(self,a):
 
    self.x//=a
 
    self.y//=a
 
    self.z//=a
 
    return self
 
    
 
  def __xor__(self,v): # vector cross product
 
    return Vector3(self.y*v.z-self.z*v.y, self.z*v.x-self.x*v.z, self.x*v.y-self.y*v.x)
 
    
 
  def __ixor__(self,v):
 
    self.x=self.y*v.z-self.z*v.y
 
    self.y=self.z*v.x-self.x*v.z
 
    self.z=self.x*v.y-self.y*v.x
 
    return self
 
    
 
  def __abs__(self):
 
    return math.sqrt(self.x*self.x + self.y*self.y + self.z*self.z)
 
    
 
  def __str__(self):
 
    return str((self.x,self.y,self.z))
 
    
 
  def __repr__(self):
 
    return 'Vector3'+self.__str__()
 
    
 
    
 
class BadOperandError(ArithmeticError):
 
  def __init__(self,u,v,message):
 
    self.u=u
 
    self.v=v
 
    self.message=message
0 comments (0 inline, 0 general)