opencv相机畸变矫正
1、畸变矫正保存加载 C++
#include <opencv2\imgproc\types_c.h>
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
Mat image, img_gray;
int BOARDSIZE[2]{ 8,11 };//棋盘格每行每列角点个数
int main()
{
vector<vector<Point3f>> object_points;//保存棋盘格上角点的三维坐标
vector<Point3f> obj_world_pts;//三维世界坐标
vector<vector<Point2f>> images_points;//保存所有角点
vector<Point2f> img_corner_points;//保存每张图检测到的角点
vector<String> images_path;//创建容器存放读取图像路径
string image_path = "./pic/chess118/*.png";//待处理图路径 F:/Works/C++/openCV/opencv study/Revise/Revise/Project1/
//vector<int> point_counts; //每幅图像中的角点的数量
glob(image_path, images_path);//读取指定文件夹下图像
//转世界坐标系
for (int i = 0; i < BOARDSIZE[1]; i++)
{
for (int j = 0; j < BOARDSIZE[0]; j++)
{
obj_world_pts.push_back(Point3f(j, i, 0));
}
}
for (int i = 0; i < images_path.size(); i++)
{
image = imread(images_path[i]);
cvtColor(image, img_gray, COLOR_BGR2GRAY);
//检测角点
bool found_success = findChessboardCorners(img_gray, Size(BOARDSIZE[0], BOARDSIZE[1]),
img_corner_points,
CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_FAST_CHECK | CALIB_CB_NORMALIZE_IMAGE);
//显示角点
if (found_success)
{
//迭代终止条件
TermCriteria criteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.001);
//进一步提取亚像素角点
cornerSubPix(img_gray, img_corner_points, Size(11, 11),
Size(-1, -1), criteria);
//绘制角点
drawChessboardCorners(image, Size(BOARDSIZE[0], BOARDSIZE[1]), img_corner_points,
found_success);
object_points.push_back(obj_world_pts);//从世界坐标系到相机坐标系
images_points.push_back(img_corner_points);
}
//char *output = "image";
char text[] = "image";
char* output = text;
imshow(output, image);
waitKey(200);
}
/*
计算内参和畸变系数等
*/
Mat cameraMatrix, distCoeffs, R, T;//内参矩阵,畸变系数,旋转量,偏移量
calibrateCamera(object_points, images_points, img_gray.size(),
cameraMatrix, distCoeffs, R, T);
cout << "cameraMatrix:" << endl;
cout << cameraMatrix << endl;
cout << "*****************************" << endl;
cout << "distCoeffs:" << endl;
cout << distCoeffs << endl;
cout << "*****************************" << endl;
cout << "Rotation vector:" << endl;
cout << R << endl;
cout << "*****************************" << endl;
cout << "Translation vector:" << endl;
cout << T << endl;
///*
//畸变图像校准
//*/
Mat src, dst;
src = imread("./pic/chess118/100000.png"); //F:/Works/C++/openCV/opencv study/Revise/image/2.jpg
undistort(src, dst, cameraMatrix, distCoeffs);
char texts[] = "image_dst";
char* dst_output = texts;
//char *dst_output = "image_dst";
imshow(dst_output, dst);
waitKey(100);
imwrite("./pic/save/1.png", dst); //保存
destroyAllWindows();//销毁显示窗口
system("pause");
return 0;
}
2、畸变矫正保存加载 python
2.1保存矩阵
import cv2 as cv
import numpy as np
import glob
import os
import scipy.io as scio
# 循环中断
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# 标定板交叉点的个数
row = 8
column = 11
objp = np.zeros((row * column, 3), np.float32)
objp[:, :2] = np.mgrid[0:row, 0:column].T.reshape(-1, 2)
objp=objp*0.02
objpoints = [] # 实际空间3D点
imgpoints = [] # 图像中2D点
# 批量读取图片
images = glob.glob('./pic/chess118/*.png') # .jpg应该改为.png
# images = glob.glob('./pic/chess68/*.jpg') # .jpg应该改为.png
i=0
for fname in images:
img = cv.imread(fname)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 找标定板角点
ret, corners = cv.findChessboardCorners(gray, (row, column), None)
if ret == True:
objpoints.append(objp)
corners2 = cv.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)
imgpoints.append(corners2)
cv.drawChessboardCorners(img, (row, column), corners, ret)
i += 1;
# cv.imwrite('./pic/corners/conimg' + str(i) + '.jpg', img)
cv.imshow('img', img)
cv.waitKey(500)
cv.destroyAllWindows()
# 标定相机
ret, Matrix, dist, rvecs, tvecs = cv.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
#对文件夹下的图片进行矫正并保存到save目录下
datadir = "./pic/chess118/"
path = os.path.join(datadir)
img_list = os.listdir(path)
for i in img_list:
img = cv.imread(os.path.join(path, i))
h, w = img.shape[:2]
newMatrix, roi = cv.getOptimalNewCameraMatrix(Matrix, dist, (w, h), 1, (w, h)) # 矫正图像
dst = cv.undistort(img, Matrix, dist, None, newMatrix)
x, y, w, h = roi
dst = dst[y:y + h, x:x + w]
cv.imwrite('./pic/save/' + i, dst)
# 计算重投影误差
tot_error = 0
for i in range(len(objpoints)):
imgpoints2, _ = cv.projectPoints(objpoints[i], rvecs[i], tvecs[i], Matrix, dist)
error = cv.norm(imgpoints[i], imgpoints2, cv.NORM_L2) / len(imgpoints2)
tot_error += error
#保存矫正的内参和畸变参数,以供下次使用
print("------------------保存内参和畸变参数-------------------")
#读取矩阵
dataFile1 = './neican.mat'
dataFile2='./jican.mat'
scio.savemat(dataFile1, {'train':Matrix})
scio.savemat(dataFile2, {'train':dist})
# #读取保存矩阵,矩阵的名字为train.mat
# data = scio.loadmat(dataFile1)
# data2 = scio.loadmat(dataFile2)
# neican = data['train']
# jican = data2['train']
# print("内参:\n", neican) # 内参数矩阵
# print("畸参:\n",jican)
print("------------保存完成----------------------------")
print("------------------各个校准参数-------------------")
# 输出参数
print('ret:\n', ret)
print('mtx:\n', Matrix)
print('dist:\n', dist)
print('rvecs:\n', rvecs)
print('tvecs:\n', tvecs)
print("total error: ", tot_error / len(objpoints))
2.1直接使用保存的矩阵
import cv2 as cv
import numpy as np
import glob
import os
import scipy.io as scio
print("------------------从文件加载内参和畸变参数-------------------")
#读取矩阵
dataFile1 = './neican.mat'
dataFile2='./jican.mat'
data = scio.loadmat(dataFile1)
data2 = scio.loadmat(dataFile2)
Matrix = data['train']
dist = data2['train']
print("内参:\n", Matrix) # 内参数矩阵
print("畸参:\n",dist)
print("------------加载完成----------------------------")
print("------------用内参和畸参对图片进行矫正----------------------------")
#对文件夹下的图片进行矫正并保存到save目录下
datadir = "./pic/chess118/"
path = os.path.join(datadir)
img_list = os.listdir(path)
for i in img_list:
img = cv.imread(os.path.join(path, i))
h, w = img.shape[:2]
newMatrix, roi = cv.getOptimalNewCameraMatrix(Matrix, dist, (w, h), 1, (w, h)) # 矫正图像
dst = cv.undistort(img, Matrix, dist, None, newMatrix)
x, y, w, h = roi
dst = dst[y:y + h, x:x + w]
cv.imwrite('./pic/save/' + i, dst)
print("------------矫正完成,矫正后的图片保存在save文件夹----------------------------")
3、效果
文章来源地址https://www.toymoban.com/news/detail-514246.html
文章来源:https://www.toymoban.com/news/detail-514246.html
到了这里,关于1、opencv相机畸变矫正的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!