# here put the import lib
import cv2
import numpy as np
import pandas as pd
from PIL import Image
from tqdm import *
fisheye_image = cv2.imread("D:/Desktop/images2/image_1695199806849999905.png")
K = np.array([
[
0
0,
1
],
[
0,
1,
0
],
[
0,
0,
1
]
])
D = np.array([
[
-0.0
],
[
-0.0
],
[
-0.0
],
[
0.0
]
])
P = np.array([
[
0,
0,
1
],
[
0,
1,
0
],
[
0,
0,
1
]
])
'''
cam_K
定义:通常,cam_K被理解为相机的内参矩阵(也称为内部参数矩阵或标定矩阵)。
参数含义:
焦距f:表示相机的焦距,是相机的一个重要参数,影响成像的放大倍数和视野范围。
图像原点相对于光心成像点的纵横偏移量(cx, cy):通常以像素为单位,表示图像中心与相机光心的偏移量。
一个像素的物理尺寸(dx, dy):表示图像中每个像素在物理空间中的大小,对于将图像坐标转换为物理坐标至关重要。
图像物理坐标的扭曲因子(有时用r或gamma表示):表示图像坐标系的扭曲程度,影响图像的几何形状。
cam_D
定义:cam_D通常指的是相机的畸变系数矩阵,用于描述相机成像过程中的畸变情况。
参数含义:
径向畸变系数(k1, k2, k3等):描述图像点从理想位置到实际位置的径向偏移量,通常表现为桶形畸变或枕形畸变。
切向畸变系数(p1, p2等):描述由于透镜和CMOS或CCD的安装位置误差导致的切向偏移量。
P
定义:在相机标定中,P通常指的是投影矩阵或摄像机矩阵,它将三维世界点投影到二维像素平面。
参数构成:P矩阵是相机内参矩阵(cam_K)和外参矩阵的乘积,即P = K[R|t],其中R是旋转矩阵,t是平移向量。
作用:P矩阵用于描述从世界坐标系到像素坐标系的转换关系,是实现三维重建、物体定位等任务的基础。
gplane
含义:在相机标定的语境中,“gplane”并不是一个标准的术语。但如果将其理解为与“平面(plane)”相关的概念,它可能指的是标定过程中使用的某个参考平面,如棋盘格平面,这个平面在世界坐标系中有一个固定的位置。在标定过程中,相机拍摄这个平面上的多个点,通过这些点的图像坐标和世界坐标来计算相机的内外参数。
注意:由于“gplane”不是相机标定中的标准术语,因此其具体含义可能因上下文而异。如果“gplane”是在某个特定的标定方法或应用中出现的,建议查阅相关文献或资料以获取准确解释。
rmsd_pixel
含义:“rmsd_pixel”可能指的是均方根位移(Root Mean Square Displacement,RMSD)在像素单位下的表示。均方根位移通常用于衡量两个图像或图像序列之间像素位置的差异,特别是在粒子追踪测速、图像配准等领域中。在相机标定的上下文中,它可能用于评估标定结果的准确性或校正图像畸变的效果。
应用:如果“rmsd_pixel”用于相机标定,它可能表示校正后的图像与理想图像(或无畸变图像)之间像素位置的差异。较小的“rmsd_pixel”值通常意味着更好的校正效果。
注意:虽然“rmsd_pixel”在相机标定中不是一个标准术语,但均方根位移(RMSD)是一个广泛使用的统计量,用于衡量数据的离散程度或差异。因此,“rmsd_pixel”可能是在某个特定的标定方法或应用中,为了描述像素级别的差异而引入的术语。
'''
## todo 基础版本
'''
calibrated_image = cv2.fisheye.undistortImage(fisheye_image, K, D)
# # 获取校正后图像的尺寸
height, width = calibrated_image.shape[:2]
# # 计算裁剪的边界
crop_size = min(height, width)
x = (width - crop_size) // 2
y = (height - crop_size) // 2
# # 裁剪图像
cropped_image = calibrated_image[y:y+crop_size, x:x+crop_size]
cv2.imwrite('D:/Desktop/image_1726810151745515230.png', cropped_image)
'''
## todo 基础矫正版本
# 获取图像的尺寸
# h, w = fisheye_image.shape[:2]
# # 计算映射
# map1, map2 = cv2.fisheye.initUndistortRectifyMap(K, D, np.eye(3), K, (w, h), cv2.CV_32FC1)
# undistorted_image = cv2.remap(fisheye_image, map1, map2, interpolation=cv2.INTER_LINEAR)
# # 显示结果
# # cv2.imshow('Undistorted Image', undistorted_image)
# # cv2.waitKey(0) # 等待用户按键
# # 保存结果
# cv2.imwrite('D:/Desktop/undistorted_image.jpg', undistorted_image) # 保存结果图像
## todo 新矫正版本---丢失信息较多
# 2. 获取新的校正后的内参矩阵
# new_K = cv2.fisheye.estimateNewCameraMatrixForUndistortRectify(K, D, fisheye_image.shape[:2], None)
# # 3. 创建去畸变映射表
# map1, map2 = cv2.fisheye.initUndistortRectifyMap(K, D, np.eye(3), new_K, fisheye_image.shape[:2], cv2.CV_16SC2)
# # 4. 使用映射表进行去畸变
# undistorted_img = cv2.remap(fisheye_image, map1, map2, interpolation=cv2.INTER_LINEAR)
# # 显示结果
# # cv2.imshow('Undistorted Image', undistorted_img)
# # cv2.waitKey(0)
# # cv2.destroyAllWindows()
# cv2.imwrite('D:/Desktop/9.jpg', undistorted_img)
## todo 更新图片----适配 1、横向展开法 2、经度矫正法 3、纬度矫正法
'''
def get_useful_area(image):
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
_,image_binary = cv2.threshold(image_gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
_,contours,_ = cv2.findContours(image_binary, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
contour_fisheye = sorted(contours,key=cv2.contourArea, reverse=True)[0]
center, radius = cv2.minEnclosingCircle(contour_fisheye)
mask = np.zeros_like(image, dtype=np.uint8)
mask = cv2.circle(mask, (int(center[0]),int(center[1])),int(radius),(1,1,1),-1)
image_userful = image*mask
image_fisheye = image_userful[int(center[1])-int(radius):int(center[1])+int(radius),int(center[0])-int(radius):int(center[0])+int(radius),:]
return image_fisheye
image = get_useful_area(fisheye_image)
## TODO 1横向展开法
# 横向展开法
R = image.shape[0]//2
W=int(2*np.pi*R)
H=R
mapx = np.zeros([H,W],dtype=np.float32)
mapy = np.zeros([H,W],dtype=np.float32)
for i in tqdm(range(mapx.shape[0])):
for j in range(mapx.shape[1]):
angle = j/W*np.pi*2
radius = H-i
mapx[i,j] = R+np.sin(angle)*radius
mapy[i,j] = R-np.cos(angle)*radius
image_remap=cv2.remap(fisheye_image,mapx,mapy,interpolation=cv2.INTER_LINEAR,borderMode=cv2.BORDER_CONSTANT)
cv2.imwrite('D:/Desktop/zhankai.jpg', image_remap) # 保存结果图像
## TODO 2经度矫正法
R=image.shape[0]//2
mapx = np.zeros([2*R,2*R],dtype=np.float32)
mapy = np.zeros([2*R,2*R],dtype=np.float32)
for i in tqdm(range(mapx.shape[0])):
for j in range(mapx.shape[1]):
mapx[i,j] = (j-R)/R*(R**2-(i-R)**2)**0.5+R
mapy[i,j] = i
image_remap=cv2.remap(image,mapx,mapy,interpolation=cv2.INTER_LINEAR,borderMode=cv2.BORDER_CONSTANT)
cv2.imwrite('D:/Desktop/jing.jpg', image_remap) # 保存结果图像
## TODO 3维度矫正法
R=image.shape[0]//2
mapx = np.zeros([2*R,2*R],dtype=np.float32)
mapy = np.zeros([2*R,2*R],dtype=np.float32)
for i in tqdm(range(mapx.shape[0])):
for j in range(mapx.shape[1]):
mapy[i,j] = (i-R)/R*(R**2-(j-R)**2)**0.5+R
mapx[i,j] = j
image_remap=cv2.remap(image,mapx,mapy,interpolation=cv2.INTER_LINEAR,borderMode=cv2.BORDER_CONSTANT)
cv2.imwrite('D:/Desktop/wei.jpg', image_remap) # 保存结果图像
'''
## TODO 棋盘矫正
'''
def distort(
img_before='D:/Desktop/images2/image_1695199806816999912.png',
img_after='D:/Desktop/undistorted_image2.jpg',
K=K,
D=D,
resolution=(3072, 2048)
):
"""使用 OpenCV 图像去畸变
:param img_before: 要处理的图像
:param img_after: 处理后的图像完整路径
:param K: 相机内参,np.array(3x3)
:param D: 相机镜头畸变系数,np.array(4x1)
:param resolution: 图像分辨率
"""
img = Image.open(img_before)
img = img.resize(resolution)
img_bgr = cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
img_distort = cv2.fisheye.undistortImage(
img_bgr,
K,
D,
None,
K,
resolution
)
img_distort = cv2.cvtColor(img_distort, cv2.COLOR_BGR2RGB)
img_distort = Image.fromarray(img_distort)
img_distort = img_distort.resize((1920, 1080))
img_distort.save(img_after)
distort()
'''
## todo 新矫正版本---更新---最解决用户的图片
def new_undistort(img_path, output_image):
fisheye_image = cv2.imread(img_path)
# 2. 使用 balance 参数计算新的校正矩阵
h, w = fisheye_image.shape[:2]
print(h,w)
# balance = 0.89 # 取值范围 0~1,越大保留越多畸变,越小校正越彻底
# new_K = cv2.fisheye.estimateNewCameraMatrixForUndistortRectify(
# K, D, (w, h), np.eye(3), balance=balance
# )
new_K = P
# 3. 创建映射表
map1, map2 = cv2.fisheye.initUndistortRectifyMap(
K, D, np.eye(3), new_K, (w, h), cv2.CV_16SC2
)
# 4. 去畸变处理
undistorted_img = cv2.remap(fisheye_image, map1, map2, interpolation=cv2.INTER_LINEAR)
cv2.imwrite(output_image, undistorted_img)
import os
img_path = r"D:\Desktop\fisheye_images"
output_path = r"D:\Desktop\new_images"
for img in os.listdir(img_path):
image_file = os.path.join(img_path,img)
out_file = os.path.join(output_path, img)
new_undistort(image_file,out_file)
fisheye 去畸变整理
于 2024-11-09 15:24:31 首次发布