Skip to content

Commit

Permalink
Broke the scantron module into several pieces.
Browse files Browse the repository at this point in the history
  • Loading branch information
philsc committed May 19, 2013
1 parent fef0490 commit 064b1b6
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 67 deletions.
4 changes: 4 additions & 0 deletions scantron/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from generator import ScantronGenerator
from parser import ScantronParser
from data import ScantronField
from reportlab.lib.units import inch
8 changes: 8 additions & 0 deletions scantron/data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env python2


class ScantronField:
def __init__(self, name, label, fieldType):
self.name = name
self.label = label
self.fieldType = fieldType
68 changes: 1 addition & 67 deletions scantron.py → scantron/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,67 +5,8 @@
from reportlab.pdfgen import canvas
from qrcode import *

import numpy as np
import scipy as sp
from scipy import ndimage
from PIL import Image, ImageDraw
import math


class ScantronParser:
def __init__(self):
pass


def scan(self, data, path):
img = Image.open(path).convert('RGB')
im = sp.misc.fromimage(img, flatten=True)
im = np.where(im > 128, 0, 1)
label_im, num = ndimage.label(im, structure=np.ones((3, 3)).tolist())
centroids = ndimage.measurements.center_of_mass(im, label_im, xrange(1,
num+1))
slices = ndimage.find_objects(label_im)

squares = []

for i in range(len(slices)):
sub_img = np.where(label_im[slices[i]] == i + 1, 1, 0)
num_ones = np.sum(sub_img)
num_all = sub_img.size
shape = sub_img.shape

ratio = float(shape[0]) / float(shape[1])
darkness = float(num_ones)/float(num_all)

if darkness > 0.95 and abs(ratio - 1.0) < 0.1 and shape[0] > 14:
x1, x2 = slices[i][1].start, slices[i][1].stop
y1, y2 = slices[i][0].start, slices[i][0].stop

draw = ImageDraw.Draw(img)
draw.rectangle([x1, y1, x2, y2], outline='blue')
del draw

squares.append(i)

if len(squares) != 3:
print('Could not uniquely identify the three page markers.')
raise Exception

squares = zip(squares, map(lambda s: sum(centroids[s]), squares))
squares = sorted(squares, key=lambda x: x[1])

for s in squares:
print('square ' + str(s))

tl = centroids[squares[0][0]]
bl = centroids[squares[1][0]]
br = centroids[squares[2][0]]

rotation = math.atan2(bl[1] - tl[1], bl[0] - tl[0])
print('rotation: ' + str(rotation))


class Scantron:
class ScantronGenerator:
def __init__(self, filename, spacing=0.3*inch):
self._fontSize = 0.15*inch

Expand Down Expand Up @@ -217,10 +158,3 @@ def populate(self, data, matches=1, collate='on'):

def save(self):
self._canvas.save()


class Field:
def __init__(self, name, label, fieldType):
self.name = name
self.label = label
self.fieldType = fieldType
60 changes: 60 additions & 0 deletions scantron/parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/usr/bin/env python2

import numpy as np
import scipy as sp
from scipy import ndimage
from PIL import Image, ImageDraw
import math


class ScantronParser:
def __init__(self):
pass


def scan(self, data, path):
img = Image.open(path).convert('RGB')
im = sp.misc.fromimage(img, flatten=True)
im = np.where(im > 128, 0, 1)
label_im, num = ndimage.label(im, structure=np.ones((3, 3)).tolist())
centroids = ndimage.measurements.center_of_mass(im, label_im, xrange(1,
num+1))
slices = ndimage.find_objects(label_im)

squares = []

for i in range(len(slices)):
sub_img = np.where(label_im[slices[i]] == i + 1, 1, 0)
num_ones = np.sum(sub_img)
num_all = sub_img.size
shape = sub_img.shape

ratio = float(shape[0]) / float(shape[1])
darkness = float(num_ones)/float(num_all)

if darkness > 0.95 and abs(ratio - 1.0) < 0.1 and shape[0] > 14:
x1, x2 = slices[i][1].start, slices[i][1].stop
y1, y2 = slices[i][0].start, slices[i][0].stop

draw = ImageDraw.Draw(img)
draw.rectangle([x1, y1, x2, y2], outline='blue')
del draw

squares.append(i)

if len(squares) != 3:
print('Could not uniquely identify the three page markers.')
raise Exception

squares = zip(squares, map(lambda s: sum(centroids[s]), squares))
squares = sorted(squares, key=lambda x: x[1])

for s in squares:
print('square ' + str(s))

tl = centroids[squares[0][0]]
bl = centroids[squares[1][0]]
br = centroids[squares[2][0]]

rotation = math.atan2(bl[1] - tl[1], bl[0] - tl[0])
print('rotation: ' + str(rotation))

0 comments on commit 064b1b6

Please sign in to comment.