fisheye 去畸变整理

# 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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值