title: Image Rectification from single camera using two points
body: <p>I'm trying to implement image rectification. I was using a software which is not available anymore. To rectify the image, the software used the height of the camera (h), the distance of two points (d1, d2) from the camera and the correspond lines in the image to the reference points (Line1, Line2).
  So the variables are:</p>
  
  <ul>
  <li>h (camera elevation);</li>
  <li>Line1, Line2 (row pixel)</li>
  <li>d1, d2 (Distance in meters from the camera)</li>
  </ul>
  
  <p>Configuration:</p>
  
  <p><img src="https://i.stack.imgur.com/LP4em.jpg" alt=""></p>
  
  <p>I tried to implement few code using OpenCV (Python) but the final result is not the same of the software. I wrote a code to calibrate the camera and a second to undistort the image and then I want to apply the rectification.
  The problem is that I'm using a single camera (take photos of a landscape) that is fixed with a fixed focal length and focus which I can't change anymore.
  Can someone tell me a good way to execute the rectification using the same way of the software or an another valid solution?</p>
  
  <p>My code for the calibration is</p>
  
  <pre><code># Numbers of corners
  n_w = 9
  n_h = 6
  patternSize = (n_w, n_h)
  # SIZE OF THE WINDOW TO IMPROVE THE COORDINATES OF CORNERS
  windowSize = (11, 11)
  # TERMINATION CRITERIA
  criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
  objp = np.zeros((n_h * n_w, 3), dtype=np.float32)
  objp[:, :2] = np.mgrid[0:n_w, 0:n_h].T.reshape(-1, 2)
  # LIST OF POINT
  objpoints = []
  imgpoints = []
  # GET ALL IMAGES
  images = glob.glob('*.jpg')
  
  for fname in images:
  img = cv2.imread(fname)
  
  # IMAGE ON GRAY SACLE
  gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  
  # fIND CORNERS
  retval, corners = cv2.findChessboardCorners(gray_img, patternSize, None)
  
  if retval == True:
      print 'Looping through image %s' % fname
      objpoints.append(objp)
      cv2.cornerSubPix(gray_img, corners, windowSize, (-1, -1), criteria)
      imgpoints.append(corners)
      cv2.drawChessboardCorners(img, patternSize, corners, retval)
      cv2.imshow('ChessBoard Image %s' % fname, img)
      cv2.waitKey(500)
      cv2.destroyAllWindows()
  
      print "------START CALIBRATION....."
      ret, cameraMatrix, distCoeffs, revcs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray_img.shape[::-1],
                                                                        None, None)
      print ret
      print cameraMatrix
      print distCoeffs
      print '---SAVING CALIBRATION DATA'
      np.savez('calibration_data', RMS=ret, distCoeffs=distCoeffs, cameraMatrix=cameraMatrix)
      if ret &lt;= 1.0:
          print '''-----GOOD CALIBRATION'''
  </code></pre>
  
  <p>The code to remove the distortion is:</p>
  
  <pre><code> # LOAD CALIBRATION DATA
   calibrationData = np.load('calibration_data.npz')
  
   distCoeffs = calibrationData['distCoeffs']
   cameraMatrix = calibrationData['cameraMatrix']
  
   calibrationData.close()
  
   # LOAD IMAGES
   images = glob.glob('/*.jpg')
  
   for i, fname in enumerate(images):
       img = cv2.imread(fname)
       # UNDISTORT
       undistorted_img = cv2.undistort(img, cameraMatrix, distCoeffs, None)
       # SAVE IMAGE
       cv2.imwrite(os.path.join(dirname, 'Undistorted_%05d.jpg' % i), undistorted_img)
       cv2.imshow('Undistorted Image %s' % fname, undistorted_img)
  </code></pre>
  
  <p>The first idea to rectify the image was to find the 4 corners inside the real world image of a trapezoid (<strong>A4 paper</strong>) and compute a transformation matrix given 4 points of a rectangle (real dimension of an <strong>A4</strong>).  But I think that is an wrong approce.
  To do this I wrote this code:</p>
  
  <pre><code>#load image
  img_Trap = cv2.imread('image.png', cv2.IMREAD_GRAYSCALE)
  #points on the image (corners of an A4 paper)
  ptsTrap = np.array(((1556, 1050), (1556, 1050), (2189, 1677), (1425, 1723)), dtype=np.float32)
  
  img_Rect = cv2.imread('image2.png', cv2.IMREAD_GRAYSCALE)
  # corner of a A4 (saving the aspect ratio)
  ptsRect = np.array(((1980, 1381), (2189, 1381), (2189, 1677), (1980, 1677)), dtype=np.float32)
  #transformation matrix
  T = cv2.getPerspectiveTransform(ptsTrap, ptsRect)
  print T
  # warp perspective
  warp = cv2.warpPerspective(img_Trap, T, img_Rect.shape[:2])
  cv2.imwrite('warpimage.png', warp)
  </code></pre>