我有以下图片是电脑生成的
它作为光学实验的输入输入,结果如下图:
正如您所见,由于使用了镜头系统,图像具有双凹效果。
我需要能够不失真地还原图像,并与原始图像进行比较。我是图像处理的新手,遇到了两个有用的 python 包:
https://pypi.org/project/defisheye/
defisheye
对我来说使用起来非常简单(下面的脚本),但到目前为止我无法获得最佳结果。
from defisheye import Defisheye
dtype = 'linear'
format = 'fullframe'
fov = 11
pfov = 10
img = "input_distorted.jpg"
img_out = "input_distorted_corrected.jpg"
obj = Defisheye(img, dtype=dtype, format=format, fov=fov, pfov=pfov)
# To save image locally
obj.convert(outfile=img_out)
来自 opencv:https://docs.opencv.org/4.x/dc/dbb/tutorial_py_calibration.html 相机校准教程超出了我的知识范围。如果有人可以向我保证这是否可行,我可以开始更深入地挖掘。非常感谢任何建议。
如果您可以使用相机简单地校准它,但如果您别无选择,最好的方法是使用软件手动进行。这里我用 GIMP 去除了镜头效果。
如果你必须务实地去做,你有两种方法。
首先: 您可以自动化 GIMP 并编写脚本来完成这件事。
第二: 在 OpenCV 中为您的相机找到最佳系数。在这里,我写了一个脚本,可以帮助您通过测试和试验找到系数。
import cv2
import numpy as np
import matplotlib.pyplot as plt
src = cv2.imread("camera.jpg")
# convert image to graysclae
src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
height, width = src_gray.shape
# set camera matrix ceofs
focal_lenght_x = 1000
focal_lenght_y = 1000
optical_center_x = 500
optical_center_y = 1000
# set distortion ceofs
k1 = k2 = 0.02
p1 = p2 = 0
k3 = 0
# create camera, distortion and new camera matrix
cameraMatrix = np.array([[focal_lenght_x,0,optical_center_x],[0,focal_lenght_y,optical_center_y], [0,0,1]])
distCoeffs = np.array([[k1, k2, p1, p2, k3]])
newcameramatrix, _ = cv2.getOptimalNewCameraMatrix(
cameraMatrix, distCoeffs, (width, height), 1, (width, height)
)
# blur image and find contours
src_blur = cv2.blur(src_gray,(13,13))
ret, thresh = cv2.threshold(src_blur, 2, 255, 0)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# find the biggest contour by area
c = max(contours, key = cv2.contourArea)
# reduce number of points in contour
epsilon = 0.003*cv2.arcLength(c,True)
approx = cv2.approxPolyDP(c,epsilon,True)
# draw biggest contour
cv2.drawContours(src, [approx], -1, (255,0,0), 3)
# undistor image
undistorted_image = cv2.undistort(
src, cameraMatrix, distCoeffs, None, newcameramatrix
)
# show original image and undistorted image with contour
fig = plt.figure()
ax1 = fig.add_subplot(1,2,1)
ax1.imshow(src)
ax2 = fig.add_subplot(1,2,2)
ax2.imshow(undistorted_image)
plt.show()
此代码绘制了图像中最大的轮廓,并显示了去畸变前后的图像。您必须找到最佳值才能使轮廓看起来像矩形。
只需改变焦距、光心、k1、k2、k3、p1、p2即可达到最佳效果。
当您找到最佳值时,使用它们来制作您的最终图像。
undistorted_image = cv2.undistort(
src_gray, cameraMatrix, distCoeffs, None, newcameramatrix
)
src_blur = cv2.blur(undistorted_image,(3,3))
ret, thresh = cv2.threshold(src_blur, 70, 255, 0)
cv2.imwrite("calibrated.png", thresh)
这是我用当前系数得到的输出。
我将做出以下假设:
避免大量计算或镜头模型的解决方案可以通过分别校准每个输入像素和输出图像之间的关系来实现。执行此操作的过程可能如下所示: