0

I wrote the following code by following the advice given in these posts: 1 2

They talk about re-distorting a set of points, not specifically an image. This is where I am stuck. How do I convert a set of points to an image?

By "points" I assumed they meant one of two things:

  • every single point in the entire image
  • points that they found off a chessboard

I dont know how to get all the points from an image. I have tried with cv2.imread('filename.jpg') but it returns a matrix with wonky formatting so I assumed that was not it. So I decided to just use chessboard points. Can I somehow convert this to the final re-distorted image?

I could not get the convertPointsToHomogeneous() method to work for me, so I just manually added a 1 to every point. Does this have the same effect?

import cv2
import numpy as np
import os
import glob
from util import Util as u

# code from 2nd link!
def distort(point):
    
    x = (point[0] - CC[0]) / FC[0]
    y = (point[1] - CC[1]) / FC[1]

    r2 = x*x + y*y

    # Radial distorsion
    xDistort = x * (1 + KC[0] * r2 + KC[1] * r2 * r2 + KC[4] * r2 * r2 * r2)
    yDistort = y * (1 + KC[0] * r2 + KC[1] * r2 * r2 + KC[4] * r2 * r2 * r2)

    # Tangential distorsion
    xDistort = xDistort + (2 * KC[2] * x * y + KC[3] * (r2 + 2 * x * x))
    yDistort = yDistort + (KC[2] * (r2 + 2 * y * y) + 2 * KC[3] * x * y)

    # Back to absolute coordinates.
    xDistort = xDistort * FC[0] + CC[0]
    yDistort = yDistort * FC[1] + CC[1]

    return [xDistort, yDistort]

# cam matrix and dist coeff's
FC, CC, KC = u.read_params_from_file()
cam_matrix, distortion = u.create_matrix_profile(FC, CC, KC)

# checkerboard values
CHECKERBOARD = (15,22)
criteria = (cv2.TERM_CRITERIA_EPS +
            cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)

# create array
dist_homo_arr = np.array([[0, 0, 0]])

# import image
images = glob.glob('*.jpg')
filename = images[0]
img = cv2.imread(filename)
grayColor = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# find chessboard points
ret, corners = cv2.findChessboardCorners( grayColor, CHECKERBOARD, cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_FAST_CHECK + cv2.CALIB_CB_NORMALIZE_IMAGE)
    
if ret == True:

    # improve chessboard points
    better_corners = cv2.cornerSubPix(grayColor, corners, (11, 11), (-1, -1), criteria)

    for point in better_corners:

        # find the distorted point and make it homogeneous
        dist_homo_point = np.append(distort(point[0]), float(1.0))

        # add the point to the 2d array
        dist_homo_arr = np.concatenate((dist_homo_arr, np.array([dist_homo_point])))

    # cut out the first part with all zero's
    dist_homo_arr = dist_homo_arr[1:dist_homo_arr.size]

    # project the 3d points back to 2d
    dist_arr_2d = cv2.projectPoints(dist_homo_arr, (0,0,0), (0,0,0), cam_matrix, distortion)

    # how do I turn this into an image?
  • I once saw someone use some analysis/algebra to numerically iteratively **invert** the `xymap` gained from `initUndistortRectifyMap` (or similar function). the answers float around on SO... https://stackoverflow.com/questions/41703210/inverting-a-real-valued-index-grid and https://twoisprime.com/opencv-remap-inverse – Christoph Rackwitz May 26 '22 at 00:43
  • if you want to apply lens distortion to a "straight" picture so it appears as if taken by the camera, then that's what you want. -- all that stuff you already found only works on individual points, not on images. lens distortion models are easy to calculate in one direction, but require numerical iterative calculations in the other direction. the directions are opposite for images and for points. – Christoph Rackwitz May 26 '22 at 00:46
  • @ChristophRackwitz thats very interesting! why are they opposite? – Imightbehigh May 26 '22 at 01:20
  • a matter of how remap() works, any proper resampling/interpolation really. it "pulls" from the source picture, rather than "pushing"/throwing forward. and that represents the inverted mapping. if you can easily calculate from P to P', and you fill the xymap for remap with those P' for every P pixel, then the application of remap actually maps P' to P, easily. – Christoph Rackwitz May 26 '22 at 12:32

0 Answers0