diff --git a/tests/test_scans.py b/tests/test_scans.py
index 5b61b30be5ecd090148589fe60acdf056279e856..79a4e7aaab2bcca76b8f09cd578f62f712ed94b5 100644
--- a/tests/test_scans.py
+++ b/tests/test_scans.py
@@ -291,15 +291,15 @@ def test_realign_image(datadir, file_name):
     test_file = os.path.join(datadir, dir_name, file_name)
     test_image = np.array(PIL.Image.open(test_file))
 
-    correct_corner_markers = [(58, 58), (1180, 58), (58, 1694), (1180, 1694)]
+    correct_corner_markers = [(59, 59), (1181, 59), (59, 1694), (1181, 1694)]
 
     result_image, result_corner_markers = scans.realign_image(test_image)
 
     assert result_corner_markers is not None
     for i in range(4):
         diff = np.absolute(np.subtract(correct_corner_markers[i], result_corner_markers[i]))
-        assert diff[0] < epsilon
-        assert diff[1] < epsilon
+        assert diff[0] <= epsilon
+        assert diff[1] <= epsilon
 
 
 def test_incomplete_reference_realign_image(datadir):
diff --git a/zesje/api/exams.py b/zesje/api/exams.py
index a1c449a05bd1ad5d5a1f50a75c7e3698d66114e5..83dd18b52229ab84363cd29a877c4cb832c34f31 100644
--- a/zesje/api/exams.py
+++ b/zesje/api/exams.py
@@ -9,14 +9,9 @@ from flask_restful import Resource, reqparse
 from werkzeug.datastructures import FileStorage
 from sqlalchemy.orm import selectinload
 
-from ..pdf_generation import generate_pdfs, output_pdf_filename_format, join_pdfs, page_is_size
+from ..pdf_generation import PAGE_FORMATS, generate_pdfs, output_pdf_filename_format, join_pdfs, page_is_size
 from ..database import db, Exam, ExamWidget, Submission
 
-PAGE_FORMATS = {
-    "A4": (595.276, 841.89),
-    "US letter": (612, 792),
-}
-
 
 def _get_exam_dir(exam_id):
     return os.path.join(
diff --git a/zesje/pdf_generation.py b/zesje/pdf_generation.py
index 09bf9641bd13e631eb02a163f69ef2959b7955d6..e4b3c2ece43bfb237c09cdfc05f2bca60507c336 100644
--- a/zesje/pdf_generation.py
+++ b/zesje/pdf_generation.py
@@ -10,6 +10,19 @@ from reportlab.pdfgen import canvas
 
 output_pdf_filename_format = '{0:05d}.pdf'
 
+# the size of the markers in points
+MARKER_FORMAT = {
+    "margin": 10 * mm,
+    "marker_line_length": 8 * mm,
+    "marker_line_width": 1 * mm,
+    "bar_length": 40 * mm
+}
+
+PAGE_FORMATS = {
+    "A4": (595.276, 841.89),
+    "US letter": (612, 792),
+}
+
 
 def generate_pdfs(exam_pdf_file, exam_id, copy_nums, output_paths, id_grid_x,
                   id_grid_y, datamatrix_x, datamatrix_y, cb_data=None):
@@ -318,15 +331,14 @@ def _add_corner_markers_and_bottom_bar(canv, pagesize):
     """
     page_width = pagesize[0]
     page_height = pagesize[1]
-    margin = 10 * mm
-    marker_line_length = 8 * mm
-    bar_length = 40 * mm
+    marker_line_length = MARKER_FORMAT["marker_line_length"]
+    bar_length = MARKER_FORMAT["bar_length"]
 
     # Calculate coordinates offset from page edge
-    left = margin
-    bottom = margin
-    right = page_width - margin
-    top = page_height - margin
+    left = MARKER_FORMAT["margin"]
+    bottom = MARKER_FORMAT["margin"]
+    right = page_width - MARKER_FORMAT["margin"]
+    top = page_height - MARKER_FORMAT["margin"]
 
     # Calculate start and end coordinates of bottom bar
     bar_start = page_width / 2 - bar_length / 2
diff --git a/zesje/scans.py b/zesje/scans.py
index 8addf7ab033a93d3809734760ae5988dec36ec45..9fbee694be950c006c6e24d57fe61345ee16e7a8 100644
--- a/zesje/scans.py
+++ b/zesje/scans.py
@@ -19,6 +19,8 @@ from .images import guess_dpi, get_box, fix_corner_markers
 from .factory import make_celery
 from .pregrader import add_feedback_to_solution
 
+from .pdf_generation import MARKER_FORMAT, PAGE_FORMATS
+
 ExtractedBarcode = namedtuple('ExtractedBarcode', ['token', 'copy', 'page'])
 
 ExamMetadata = namedtuple('ExamMetadata', ['token', 'barcode_coords'])
@@ -791,7 +793,7 @@ def check_corner_keypoints(image_array, keypoints):
 
 
 def realign_image(image_array, keypoints=None,
-                  reference_keypoints=None):
+                  reference_keypoints=None, page_format="A4"):
     """
     Transform the image so that the keypoints match the reference.
 
@@ -815,7 +817,7 @@ def realign_image(image_array, keypoints=None,
         New keypoints properly aligned.
     """
 
-    if(keypoints is None):
+    if(not keypoints):
         keypoints = find_corner_marker_keypoints(image_array)
         check_corner_keypoints(image_array, keypoints)
 
@@ -823,8 +825,10 @@ def realign_image(image_array, keypoints=None,
         keypoints = fix_corner_markers(keypoints, image_array.shape)
 
     # use standard keypoints if no custom ones are provided
-    if (reference_keypoints is None):
-        reference_keypoints = [(59, 59), (1179, 59), (59, 1693), (1179, 1693)]
+    if (not reference_keypoints):
+        # reference_keypoints = [(59, 59), (1179, 59), (59, 1693), (1179, 1693)]
+        dpi = guess_dpi(image_array)
+        reference_keypoints = generate_perfect_corner_markers(page_format, dpi)
 
     if (len(reference_keypoints) != 4):
         # this function assumes that the template has the same dimensions as the input image
@@ -848,3 +852,15 @@ def realign_image(image_array, keypoints=None,
         return_keypoints = fix_corner_markers(return_keypoints, return_image.shape)
 
     return return_image, return_keypoints
+
+
+def generate_perfect_corner_markers(format="A4", dpi=200):
+    left_x = MARKER_FORMAT["margin"]/72 * dpi
+    top_y = MARKER_FORMAT["margin"]/72 * dpi
+    right_x = (PAGE_FORMATS[format][0] - MARKER_FORMAT["margin"])/72 * dpi
+    bottom_y = (PAGE_FORMATS[format][1] - MARKER_FORMAT["margin"])/72 * dpi
+
+    return [(left_x, top_y),
+            (right_x, top_y),
+            (left_x, bottom_y),
+            (right_x, bottom_y)]