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?