1、opencv相机畸变矫正

opencv相机畸变矫正

  • opencv相机畸变矫正
    • 1、畸变矫正保存加载 C++
    • 2、畸变矫正保存加载 python
      • 2.1保存矩阵
      • 2.1直接使用保存的矩阵
    • 3、效果

opencv相机畸变矫正

1、畸变矫正保存加载 C++

#include 
#include
#include
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 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、效果

1、opencv相机畸变矫正_第1张图片

你可能感兴趣的:(机器视觉,opencv,计算机视觉,人工智能)