diff --git a/src/gui/mainwindow.py b/src/gui/mainwindow.py
--- a/src/gui/mainwindow.py
+++ b/src/gui/mainwindow.py
@@ -1,56 +1,27 @@
-import logging as log
 import tkinter as tk
 from tkinter import N,S,E,W
 
-from PIL import ImageTk
-
-import config
-import imageanalyzer
-from corners import Corners
-from epoint import EPoint
-from grid import Grid
 from .boardview import BoardView
+from .imgview import ImgView
 
 
 class MainWindow(tk.Frame):
 	def __init__(self,parent,master=None):
 		self.parent=parent
-		self.corners=Corners()
-
-		self.currentFrame=None
-		self._boardGrid=None
-
-		self.img=None
-		self._imgSizeCoef=1
-		self._imgShift=EPoint(0,0)
 
 		tk.Frame.__init__(self, master)
 		self.grid(column=0,row=0,sticky=(N,S,E,W))
 		self._createWidgets()
 
 	def setCurrentFrame(self,frame):
-		self.currentFrame=frame
-
-		w=int(self.imgView['width'])
-		h=int(self.imgView['height'])
-		wo,ho=frame.size # o for original
-		widthRatio=wo/w
-		heightRatio=ho/h
-		self._imgSizeCoef=max(widthRatio,heightRatio)
-		# shift compensates possible horizontal or vertical empty margins from unmatching aspect ratios
-		self._imgShift=EPoint(wo-w*self._imgSizeCoef,ho-h*self._imgSizeCoef)/2
-
-		frame.thumbnail((w,h)) # resize
-		self.img=ImageTk.PhotoImage(frame)
+		self.imgView.setImg(frame)
 
 	def _createWidgets(self):
 		# a captured frame with overlay graphics
-		self.imgView=tk.Canvas(self)
-		self.imgView.configure(width=480,height=360,background="#ff00ff")
+		self._imgWrapper=tk.Frame(self,width=480,height=360)
+		self.imgView=ImgView(self._imgWrapper,self)
 
-		self.imgView.bind('<1>',lambda e: self.addCorner(e.x,e.y))
-
-		self.imgView.grid(column=0,row=0,sticky=(N,S,E,W))
+		self._imgWrapper.grid(column=0,row=0,sticky=(N,S,E,W))
 
 		# board with detected stones
 		self._boardWrapper=tk.Frame(self,width=360,height=360)
@@ -70,54 +41,14 @@ class MainWindow(tk.Frame):
 		self.rowconfigure(0,weight=1)
 
 		# render everything
-		self.redrawImgView()
-
-	## Stores a grid corner located at x,y coordinates.
-	def addCorner(self,x,y):
-		self.corners.add(x,y)
-		log.debug("click on %d,%d",x,y)
-		log.debug("sizeCoef: %f, shift: %d,%d",self._imgSizeCoef,self._imgShift.x,self._imgShift.y)
-		if self.corners.canonizeOrder():
-			# transform corners from show coordinates to real coordinates
-			log.debug(self.corners.corners)
-			self._boardGrid=Grid(self.corners.corners)
-			corners=[(c*self._imgSizeCoef+self._imgShift) for c in self.corners.corners]
-			self.parent.sendMsg("setCorners",(corners,))
-
-		self.redrawImgView()
+		self.imgView.redraw()
 
 	## Redraws the current image and its overlay.
 	def redrawImgView(self):
-		if self.currentFrame and self.img:
-			self.imgView.create_image(240,180,anchor="center",image=self.img)
-
-		for corner in self.corners.corners:
-			self.markPoint(corner.x,corner.y)
-
-		if self._boardGrid!=None and config.gui.showGrid:
-			for r in range(19):
-				a=self._boardGrid.intersections[r][0]
-				b=self._boardGrid.intersections[r][-1]
-				self.imgView.create_line(a.x,a.y,b.x,b.y,fill='#00ff00')
-			for c in range(19):
-				a=self._boardGrid.intersections[0][c]
-				b=self._boardGrid.intersections[-1][c]
-				self.imgView.create_line(a.x,a.y,b.x,b.y,fill='#00ff00')
-
-		if self._boardGrid!=None and config.gui.showBigPoints:
-			for r in range(19):
-				for c in range(19):
-					((r1,c1),(r2,c2))=imageanalyzer.relevantRect(self._boardGrid.intersections[r][c], *(self._boardGrid.stoneSizeAt(r, c)))
-					self.imgView.create_rectangle(r1,c1,r2,c2,outline="#00ffff")
-
-		self.imgView.grid()
-
-	## Marks a point at the image with a green cross. Used for corners.
-	def markPoint(self,x,y):
-		self.imgView.create_line(x-3,y-3,x+4,y+4,fill="#00ff00")
-		self.imgView.create_line(x-3,y+3,x+4,y-4,fill="#00ff00")
-
-		self.imgView.grid()
+		self.imgView.redraw()
 
 	def refreshTresholds(self,_):
 		self.parent.sendMsg("setTresholds",tuple(),{"tresB":self.scaleTresB.get(), "tresW":self.scaleTresW.get()})
+
+	def sendMsg(self,actionName,args=tuple(),kwargs=None):
+		self.parent.sendMsg(actionName,args,kwargs)