Skip to content
Open-source scantron software implementation
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
cmake
examples Added picture of website Sep 24, 2017
qtcreator Added form, updated Readme, updated QtCreator files Aug 4, 2014
website Fixed HTML escaping of filename in website Nov 13, 2014
.gitignore Use dist^2 instead of sqrt(dist^2) Aug 27, 2014
Makefile Note have to compile PoDoFo with C++11 Sep 24, 2017
README.md Forgot what the extension was Sep 24, 2017
blobs.cpp Faster Blobs algorithm Aug 8, 2014
blobs.h
box.cpp Moved includes, some messages only for CLI mode Aug 7, 2014
box.h Moved includes, some messages only for CLI mode Aug 7, 2014
boxes.cpp Moved includes, some messages only for CLI mode Aug 7, 2014
boxes.h Moved includes, some messages only for CLI mode Aug 7, 2014
cores.cpp
cores.h Start processing images as soon as they are read Jul 31, 2013
data.cpp initial scoring and grading code Mar 28, 2013
data.h Moved includes, some messages only for CLI mode Aug 7, 2014
disjointset.h
extract.cpp
extract.h Image extraction: handle ICCBased color space, handle 1-bit P4 bitmap Oct 5, 2014
forms.cpp Statuses added to queue, RPC thread monitors queue Aug 8, 2014
forms.h
freetron.cpp Output as a CSV file Oct 19, 2014
histogram.cpp Moved includes, some messages only for CLI mode Aug 7, 2014
histogram.h
log.cpp
log.h
maputils.h
math.cpp Use dist^2 instead of sqrt(dist^2) Aug 27, 2014
math.h Minor fixes Sep 17, 2014
options.h
outline.cpp Keep sorted list of points we've been to in Outline Mar 23, 2015
outline.h Keep sorted list of points we've been to in Outline Mar 23, 2015
pixels.cpp Database locking, smart pointers, JS messages Aug 13, 2014
pixels.h Only add image to queue if it was loaded Aug 8, 2014
processor.cpp Note have to compile PoDoFo with C++11 Sep 24, 2017
processor.h
read.cpp Moved includes, some messages only for CLI mode Aug 7, 2014
read.h Moved includes, some messages only for CLI mode Aug 7, 2014
rotate.cpp Moved includes, some messages only for CLI mode Aug 7, 2014
rotate.h Moved includes, some messages only for CLI mode Aug 7, 2014
threadqueue.h A website processing status updates implementation Aug 2, 2014
threadqueuevoid.h A website processing status updates implementation Aug 2, 2014

README.md

freetron

A professor encouraged me to write a software implementation of a scantron machine. It's licensed under the ISC or MIT licenses. The goal was to scan a PDF of the key and all the students' sheets, grade, email the students their grade and a copy of their sheet, and then display statistics about the exam. While the program doesn't quite do all that, it does grade scanned forms and provide a website interface for convenience. Feel free to try it out and improve it.

At the moment this only supports one type of form available directly from Apperson or in website/files/form.pdf.

Using

You can either use this as a command-line utility or run it as a daemon providing a website interface.

Dependencies

a C++11 compiler
CppDB (Boost or MIT)
CppCMS (LGPL)
PoDoFo (LGPL)
OpenIL/DevIL (LGPL)
libtiff (custom: http://www.libtiff.org/misc.html)

Note: PoDoFo must be compiled with C++11 not C++98 otherwise it won't extract images. You can modify the CMakeLists.txt file. For Arch, look at my PKGBUILD for podofo-cpp11 and for freetron.

Compiling

make: make; make install
cmake: cd cmake; cmake .; make; make install

I have tested g++ and clang++ on Linux. For Mac you'll find most of the dependencies in Macports, Fink, Homebrew, or whatever you use, but you'll probably have to build CppCMS and CppDB. On Windows you'll have to build basically all of these.

Note: Use cmake if you want the keys generated on install; otherwise, use make and then generate the keys and put them in /srv/freetron or whatever website directory you choose:

cppcms_make_key --hmac sha256 --cbc aes256 \
    --hmac-file website/hmac.txt --cbc-file website/cbc.txt

Running

Website interface: ./freetron --daemon website/
Command line interface: ./freetron -i KeyID form.pdf

Example

Download a computer-generated form or a scanned form created from the Apperson form mentioned above. Below is the output of these two example forms. The first takes about 1 second and the second about 3 seconds on my computer.

$ ./freetron -i 123456789 freetron_example.pdf 2>/dev/null
ID          Answers (key first)
123456789   A B C D E A B C D E A B C D E
1233224     A A D D D A B C D E A B B C E
987444      A B C D E E D C B A B C D E D

Scores
  987444      40.00%
  1233224     66.67%

$ ./freetron -i 1793240 freetron_example2.pdf 2>/dev/null
ID          Answers (key first)
1793240     E D B B C A B D C B D A D E E B D C E C A A E C C D C C C E C E E D D A C B E A D E A A A C D A E A
888324401   D D B B C C B D A B D A E E E B D C B C A B E C D D C C E E C D D D A A C A A A D A A B A C D A E A
3741083751  _ C C C B A B D C B C A D D E A D D E A A A E C D D E A C B C E E E D C C E E C C E B A _ E B A E B

Scores
  888324401   70.00%
  3741083751  52.00%

If you specify the -d option, it'll generate debug images, which allows you to find any problematic bubbles or boxes. Below is the output from the third page of the example scanned form. Note that since OpenIL doesn't allow multi-threading, this greatly extends the run time.

Freetron Debug Image

If you run the examples in the website, you get: Freetron Website

Navigating the Code

If you want to extend or modify this program, this summary of what the different portions do may be useful.

options -- All parameters for the supported style of forms (e.g. bubble aspect ratio)

Core functionality

extract -- Extract the images from the PDF
processor -- Manage the extracting and processing threads, what to do with each image, etc. Basically, if you want to extend this program, you would add additional code to the end of parseImage.
read -- Find filled bubbles for the answers, ID, etc. on the form.
rotate -- Determine the rotation from the list of black boxes on the left and bottom of the form.

Image processing

blobs -- Connected-component labeling of black objects in image
histogram -- Self explanatory
box -- Taking a starting pixel, determine if the object that point is a part of is actually one of those black boxes on the left and bottom.
outline -- Contour tracing. Given a starting point, get a vector of points on the boundary of that object.
boxes -- Find the blobs and determine if each is a box.

Data structures

forms -- Each form (on the command line you will have only one) stores all the information needed about it and the individual pages of that form.
pixels -- Data structure for storing pixel data
data -- Data structures for coordinates, answers, etc.
disjointset -- Used in the connected-component labeling.

Utilities

log -- Log messages will be put at end of output
maputils -- Iterators and whatnot
math -- All the distance, average, stdev, etc. functions
threadqueue(void) -- Run the processing in a number of threads.
cores -- Get the number of cores for determining the number of threads to use.

Website

The website uses CppCMS, so you may want to become acquainted with that to understand this code.

website -- Main website application
rpc -- Get/set data for Javascript RPC
database -- Manage saving/reading database information using CppDB
date -- Access the date in a thread-safe way
content, skin, *.tmpl, *.js, *.css -- For the page templates and website design

You can’t perform that action at this time.