基于 python+OpenCV 超大图片的畸变矫正

  • 适用情况
  • 简略的理论分析
    • 径向畸变
    • 切向畸变
  • 问题所在
  • 解决办法
  • 完整代码
    • 在超大图片上的畸变矫正的效果

适用情况

网上大部分的镜头畸变矫正的例子都是给的小图片的测试效果,照搬他们的代码测试的话会发现,在他们给的小图片上效果良好,但是应用到自己的 超大图片(4000×3000像素) 上后会发现边缘效果很不理想!效果如下:

原图(4000×3000像素)(实验室镜头较好,看不出明显的畸变)

矫正后的效果(4000×3000像素)(仔细对比观察中间4×4的方格可以发现更加垂直了,但边缘部分形变严重)

接下来将先从理论方面为大家分析后,再附上代码,如果对理论不感兴趣也可以直接看代码


简略的理论分析

镜头畸变分为径向畸变切向畸变两部分

径向畸变

其中径向畸变的修正采用主点周围的泰勒级数展开式的前几项进行描述,下面的公式中采用了 k1,k2,k3 三项来进行描述

注意:使用的展开项越多,镜头畸变矫正越准确!


切向畸变


畸变模型可以用两个额外的参数p1和p2来描述


问题所在

使用cv2.calibrateCamera函数默认只返回 k1,k2,k3!!!

这将导致当 r 增大时,矫正时的误差会越来越大,对于100×100像素的小图片来说 r 最大也只有 50250\sqrt2502​ ,而对于4000×3000的超大图片而言,r 最大可以达到 2500,公式中当取到 r3r^3r3 时,误差将呈几何式增长


解决办法

查看OpenCV官网中cv2.calibrateCamera函数说明文档,发现该函数有一个参数flags,可以通过该参数控制返回的畸变系数的数量等高级设置

可以通过设置 flags=cv2.CALIB_RATIONAL_MODEL来控制最后返回的畸变系数数量,除了返回 k1,k2,k3,p1,p2 外,多返回 k4,k5,k6 的值

通过这样一个小的修改即可解决超大图片畸变矫正边缘形变的问题


完整代码

import cv2
import numpy as np
import glob# 阈值
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)# w h分别是棋盘格模板长边和短边规格(角点个数)
w = 5
h = 5dir = 'train_image/*.jpg'  # 所有图片数据
re_im = 'test_image/Image.jpg'  # 要矫正的图像sign_im = 'sign_image/' + 'sign.jpg'
sv_im = 'adjust_image/' + 'adjust.jpg'# 世界坐标系中的棋盘格点
objp = np.zeros((w*h, 3), np.float32)  # 构造0矩阵,用于存放角点的世界坐标
objp[:, :2] = np.mgrid[0:w, 0:h].T.reshape(-1, 2)  # 三维网格坐标划分# 储存棋盘格角点的世界坐标和图像坐标对
objpoints = []  # 在世界坐标系中的三维点
imgpoints = []  # 在图像平面的二维点images = glob.glob(dir)for fname in images:img = cv2.imread(fname)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# cv2.imshow('picture', gray)# cv2.waitKey()# cv2.destroyAllWindows()# 粗略找到棋盘格角点 这里找到的是这张图片中角点的亚像素点位置,共7×7 = 49个点,gray必须是8位灰度或者彩色图,(w,h)为角点规模ret, corners = cv2.findChessboardCorners(gray, (w, h))# 如果找到足够点对,将其存储起来if ret is True:# 精确找到角点坐标corners = cv2.cornerSubPix(gray, corners, (3, 3), (-1, -1), criteria)# 将正确的objp点放入objpoints中objpoints.append(objp)imgpoints.append(corners)# 将角点在图像上显示cv2.drawChessboardCorners(img, (w, h), corners, ret)cv2.imwrite(sign_im, img)  # 保存图片# cv2.imshow('findCorners', img)# cv2.waitKey()
# cv2.destroyAllWindows()# 标定
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None, flags=cv2.CALIB_RATIONAL_MODEL)
# ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)# 去畸变
img2 = cv2.imread(re_im)
h, w = img2.shape[:2]newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 1, (w, h))  # 自由比例参数dst = cv2.undistort(img2, mtx, dist, None, newcameramtx)cv2.imwrite(sv_im, dst)  # 保存图片
# cv2.imshow('undistort_picture', dst)
# cv2.waitKey()
# cv2.destroyAllWindows()# 反投影误差
total_error = 0
for i in range(len(objpoints)):imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)error = cv2.norm(imgpoints[i], imgpoints2, cv2.NORM_L2)/len(imgpoints2)total_error += error
print("total error: ", total_error/len(objpoints))

在超大图片上的畸变矫正的效果

原图(4000×3000像素)

矫正后的效果(4000×3000像素)(仔细对比观察可以看到矫正后的图片左侧有一条黑线,图像也略微向右聚拢了一些)

超大图片(4000×3000像素)的畸变矫正,python+OpenCV实现相关推荐

  1. python图片转视频加特效_使用Python opencv实现视频与图片的相互转换

    因为最近要经常转换数据集进行实验,因此记录一下. 1.视频转图片 即为将视频解析为一帧一帧的图片: import cv2 vc=cv2.VideoCapture("/home/hqd/Pyc ...

  2. python opencv获取图片分辨率_python-opencv遍历图片像素,并对像素进行操作

    看代码: def access_pixels(frame): print(frame.shape) #shape内包含三个元素:按顺序为高.宽.通道数 height = frame.shape[0] ...

  3. python opencv 等比例调整(缩放)图片分辨率大小代码 cv2.resize()

    # -*- coding: utf-8 -*- """ @File : 200113_等比例调整图像分辨率大小.py @Time : 2020/1/13 13:38 @A ...

  4. Qt + Python + OpenCV图标替换工具 之 获取颜色及生成图片(二)

    目录 上一篇博文 程序的下载地址以及源码 获取颜色及生成图片 判断颜色 生成转换后的图片 上一篇博文 Qt + Python + OpenCV图标替换工具 之 项目介绍(一) https://blog ...

  5. python opencv 摄像头标定_(五)单目摄像头标定与畸变矫正(C++,opencv)

    本文将梳理一种单目摄像头标定和矫正的方法,在梳理的过程中,首先使用网上离线的图片数据跑通流程,然后接入自己的camera,手动采集标定图像,实时矫正相机的畸变,然后输出矫正后的图像.全文基于Openc ...

  6. 鱼眼摄像头的畸变矫正方法-python+opencv

    鱼眼摄像头畸变校正的方法: 1. 棋盘矫正法 2. 经纬度矫正法. 相机为什么会出现畸变? 当前相机的畸变主要分为径向畸变和切向畸变两种. 径向畸变产生的原因:相机的光学镜头厚度不均匀,离镜头越远场景 ...

  7. python如何将图片的像素矩阵绘制成图片(python,matplotlib):TypeError: Invalid shape (1, 28, 28) for image data

    矩阵变成图片,这个问题使用(python , matplotlib ) 可以轻松实现. import matplotlib.pyplot as plt #使用格式 plt.imshow(x)#其中x为 ...

  8. 用python制作马赛克式/蒙太奇拼图(小图片作为像素拼成大图片)

    小时候看见课本上有用人的照片作为基本元素拼出来的人脸,感觉特别有趣,后来学了ps发现ps做不出来这个效果(其实可以,但是人工很重,效果也不好.具体见:https://www.zhihu.com/que ...

  9. python统计RGB图片某像素的个数

    1.对于RGB三通道图片,直接用两层for循环的话,效率比较低 2.可以先将RGB图片转为灰度图片,再利用numpy.where的广播机制统计像素个数.这里有一个前提是提前知道与灰度图片的像素值相对应 ...

  10. 一文讲透鱼眼相机畸变矫正,及目标检测项目应用

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 1 个人介绍 大家好,我是潘大强. 目前博士毕业4年,主要从事智能安防行业. 之前也分享过AI从业的一 ...

最新文章

  1. 使用傅里叶变换进行图像边缘检测
  2. 网站推广期间要学会筛选关键词,有利于提升网站推广转化率
  3. S3C6410 KeyPad驱动(上)
  4. 使用Cordova将您的前端JavaScript应用打包成手机原生应用
  5. php根据分辨率跳转,使用PHP将分辨率转换为Aspect比率
  6. 为什么C语言成了大学的必修课?
  7. 原生js系列之DOM工厂模式
  8. 你知道kernel version的实现原理和细节吗
  9. python open file mode description
  10. td外边加div为啥不隐藏_那些不常见,但却非常实用的 css 属性
  11. authware课件
  12. 课题申报书范文_课题优秀申报书 课题申报书范例
  13. Go语言入门【7】指针
  14. 深谈德国车和日本车的区别--觉得分析的还算冷静客观
  15. 联想lenovo sl700 240G sata ps3111主控+未知颗粒 掉盘,ps3111写保护开卡量产修复过程
  16. 【JC-2 DC220V冲击继电器】
  17. getPhoneNumber:fail no permission
  18. SAS PROC TABULATE学习笔记01
  19. 分糖果游戏c语言程序设计,C语言实例 10个小孩分糖果
  20. 最新消息:2022高被引科学家名单已公布,都想成为高被引,到底应该怎么做?(附名单)

热门文章

  1. 支持Kubernetes集群运维审计,JumpServer v2.2.0发布丨Release Notes
  2. 将中划线转为驼峰式写法
  3. 米兰•昆德拉 漂浮的一生
  4. mysql数据库命令备份还原
  5. iReasoning MIB Browser显示中文乱码问题
  6. 卡内基梅隆 计算机音乐,卡内基梅隆大学音乐技术专业申请要求
  7. APP - K歌之王请进!全民K歌可一键分享到微信状态
  8. win10打开视频显示服务器运行失败,apache启动失败,详细教您快速解决Win10系统apache启动失败...
  9. Golang chan的任务分发和优雅退出
  10. S3C2440原理图导读