Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Homography Transform for Systematic Registration Errors (Deviations in Bottom Right Corner) #309

Open
TapuCosmo opened this issue Sep 24, 2024 · 0 comments

Comments

@TapuCosmo
Copy link
Contributor

TapuCosmo commented Sep 24, 2024

On some Silhouette devices, cutting with registration marks may have systematic errors that are not representable by an affine transform. These errors manifest as cut offset errors that progressively worsen toward the bottom right corner of the page (particularly, lines that are parallel in the design are slightly off parallel when cut). This means that the devices are unable to internally correct for these types of errors using only the 3 registration marks. By computing a homology transform based on measured errors in the 4 corners of a page, these types of errors can be corrected for in software, greatly improving cut accuracy in the bottom right quadrant of each page.

I don't know how to implement this in the GUI in a user-friendly manner, so I will post my edits below for anyone who is interested in this solution:

--- a/inkscape-silhouette/silhouette/Graphtec.py
+++ b/inkscape-silhouette-mod/silhouette/Graphtec.py
@@ -26,6 +26,7 @@ import os
 import re
 import sys
 import time
+import numpy
 
 usb_reset_needed = False  # https://github.com/fablabnbg/inkscape-silhouette/issues/10
 
@@ -1179,7 +1180,7 @@ Alternatively, you can add yourself to group 'lp' and logout/login.""" % (self.h
     return x, y, inside
 
 
-  def plot_cmds(self, plist, bbox, x_off, y_off):
+  def plot_cmds(self, plist, bbox, x_off, y_off, regmark):
     """
         bbox coordinates are in mm
         bbox *should* contain a proper { 'clip': {'llx': , 'lly': , 'urx': , 'ury': } }
@@ -1210,6 +1211,32 @@ Alternatively, you can add yourself to group 'lp' and logout/login.""" % (self.h
     # Update the code to use millimeters in all places to prevent mixing with device units.
     # The conversion to SU (SilhouetteUnits) will be done in command create function.
     # Removing all kinds of multiplying, dividing and rounding.
+    
+    if regmark:
+      quad_offsets = numpy.array([
+        [0.0, 0.0],
+        [-0.1, -0.1],
+        [-0.33, -0.1],
+        [-0.27, 0.1]
+      ])
+      quad_dest = numpy.array([
+        [25.75, 19.40],
+        [178.15, 19.40],
+        [25.75, 228.60],
+        [178.15, 228.60]
+      ]) + [x_off, y_off]
+      quad_src = quad_dest + quad_offsets
+      calc_matrix = []
+      for i in range(len(quad_src)):
+        src_x = quad_src[i][0]
+        src_y = quad_src[i][1]
+        dest_x = quad_dest[i][0]
+        dest_y = quad_dest[i][1]
+        calc_matrix.append([src_x, src_y, 1, 0, 0, 0, -dest_x * src_x, -dest_x * src_y, -dest_x])
+        calc_matrix.append([0, 0, 0, src_x, src_y, 1, -dest_y * src_x, -dest_y * src_y, -dest_y])
+      calc_matrix = numpy.asarray(calc_matrix)
+      _, _, Vh = numpy.linalg.svd(calc_matrix)
+      H = Vh[-1, :]
 
     if bbox is None: bbox = {}
     bbox['count'] = 0
@@ -1227,6 +1254,11 @@ Alternatively, you can add yourself to group 'lp' and logout/login.""" % (self.h
       if len(path) < 2: continue
       x = path[0][0] + x_off
       y = path[0][1] + y_off
+      # Apply homography transform
+      denom = H[6] * x + H[7] * y + H[8]
+      x = (H[0] * x + H[1] * y + H[2]) / denom
+      y = (H[3] * x + H[4] * y + H[5]) / denom
+      
       _bbox_extend(bbox, x, y)
       bbox['count'] += 1
 
@@ -1238,6 +1270,11 @@ Alternatively, you can add yourself to group 'lp' and logout/login.""" % (self.h
       for j in range(1,len(path)):
         x = path[j][0] + x_off
         y = path[j][1] + y_off
+        # Apply homography transform
+        denom = H[6] * x + H[7] * y + H[8]
+        x = (H[0] * x + H[1] * y + H[2]) / denom
+        y = (H[3] * x + H[4] * y + H[5]) / denom
+        
         _bbox_extend(bbox, x, y)
         bbox['count'] += 1
 
@@ -1389,7 +1426,7 @@ Alternatively, you can add yourself to group 'lp' and logout/login.""" % (self.h
 
     bbox['clip'] = {'urx':width, 'ury':top, 'llx':left, 'lly':height}
     bbox['only'] = bboxonly
-    cmd_list = self.plot_cmds(pathlist,bbox,offset[0],offset[1])
+    cmd_list = self.plot_cmds(pathlist,bbox,offset[0],offset[1],regmark)
     print("Final bounding box and point counts: " + str(bbox), file=self.log)
 
     if bboxonly == True:

Instructions:

  1. Place horizontal and vertical guides running through the center of the lines of the bottom left and top right registration marks.
  2. Place a +-shaped cut path in each corner of the page (inside the area bounded by the registration marks).
  3. Digitally measure the distances (in mm to at least two decimal places) between the intersection point of each placed marker and the left and top registration bounds. Input these positions into quad_dest as a list of [x, y] coordinates.
  4. Print and cut the page with registration marks enabled.
  5. Using calipers, measure the x and y offsets (in mm to at least one decimal place) of the actual cuts with respect to the printed markers (right and down are positive). Input these offsets into quad_offsets in the same marker order as quad_dest. Save the modified Graphtec.py and replace the existing one in the Inkscape extensions/silhouette directory.
  6. Reprint and cut the page without changing any other settings. The cuts at the 4 corners should have nearly perfect aalignment now.
@TapuCosmo TapuCosmo changed the title Homology Transform for Systematic Registration Errors (Deviations in Bottom Right Corner) Homography Transform for Systematic Registration Errors (Deviations in Bottom Right Corner) Sep 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant