Zi 字媒體
2017-07-25T20:27:27+00:00
OpenCV 求焦距[純粹收集]
資料來源:
C++ OPENCV 相機內部參數
00.https://www.itread01.com/article/1515554521.html
01.https://www.oudahe.com/p/46522/
python OPENCV 相機內部參數
02.https://www.itread01.com/article/1525761600.html
03.https://blog.csdn.net/u010128736/article/details/52875137
GITHUB:https://github.com/jash-git/OpenCV-focal-length
C++
#include
#include
#include
#include
#include
#include
#include
class CameraCalibrator
{
private:
//世界座標
std::vector < std::vector> objectPoints;
//影象座標
std::vector > imagePoints;
//輸出矩陣
cv::Mat camerMatirx;
cv::Mat disCoeffs;
//標記
int flag;
//去畸變引數
cv::Mat map1, map2;
//是否去畸變
bool mustInitUndistort;
///儲存點資料
void addPoints(const std::vector&imageConers, const std::vector&objectConers)
{
imagePoints.push_back(imageConers);
objectPoints.push_back(objectConers);
}
public:
CameraCalibrator() :flag(0), mustInitUndistort(true){}
//開啟棋盤圖片,提取角點
int addChessboardPoints(const std::vector&filelist,cv::Size &boardSize)
{
std::vectorimageConers;
std::vectorobjectConers;
//輸入角點的世界座標
for (int i = 0; i < boardSize.height; i++)
{
for (int j = 0; j < boardSize.width; j++)
{
objectConers.push_back(cv::Point3f(i, j, 0.0f));
}
}
//計算角點在影象中的座標
cv::Mat image;
int success = 0;
for (int i = 0; i < filelist.size(); i++)
{
image = cv::imread(filelist[i],0);
//找到角點座標
bool found = cv::findChessboardCorners(image, boardSize, imageConers);
cv::cornerSubPix(image,
imageConers,
cv::Size(5, 5),
cv::Size(-1, -1),
cv::TermCriteria(cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS,
30, 0.1));
if (imageConers.size() == boardSize.area())
{
addPoints(imageConers, objectConers);
success++;
}
//畫出角點
cv::drawChessboardCorners(image, boardSize, imageConers, found);
cv::imshow("Corners on Chessboard", image);
cv::waitKey(100);
}
return success;
}
//相機標定
double calibrate(cv::Size&imageSize)
{
mustInitUndistort = true;
std::vectorrvecs, tvecs;
//相機標定
return cv::calibrateCamera(objectPoints, imagePoints, imageSize,
camerMatirx, disCoeffs, rvecs, tvecs, flag);
}
///去畸變
cv::Mat remap(const cv::Mat &image)
{
cv::Mat undistorted;
if (mustInitUndistort)
{
//計算畸變引數
cv::initUndistortRectifyMap(camerMatirx, disCoeffs,
cv::Mat(), cv::Mat(), image.size(), CV_32FC1, map1, map2);
mustInitUndistort = false;
}
//應用對映函式
cv::remap(image, undistorted, map1, map2, cv::INTER_LINEAR);
return undistorted;
}
//常成員函式,獲得相機內參數矩陣、投影矩陣資料
cv::Mat getCameraMatrix() const { return camerMatirx; }
cv::Mat getDistCoeffs() const { return disCoeffs; }
};
#include"CameraCalibrator.h"
#include
#include
int main()
{
CameraCalibrator Cc;
cv::Mat image;
std::vector filelist;
cv::namedWindow("Image");
for (int i = 1; i <= 22; i++)
{
///讀取圖片
std::stringstream s;
s << "D:/images/chessboards/chessboard" << std::setw(2) << std::setfill('0') << i << ".jpg";
std::cout << s.str() << std::endl;
filelist.push_back(s.str());
image = cv::imread(s.str(),0);
cv::imshow("Image", image);
cv::waitKey(100);
}
//相機標定
cv::Size boardSize(6, 4);
Cc.addChessboardPoints(filelist, boardSize);
Cc.calibrate(image.size());
//去畸變
image = cv::imread(filelist[1]);
cv::Mat uImage=Cc.remap(image);
cv::imshow("原影象", image);
cv::imshow("去畸變", uImage);
//顯示相機內參數矩陣
cv::Mat cameraMatrix = Cc.getCameraMatrix();
std::cout << " Camera intrinsic: " << cameraMatrix.rows << "x" << cameraMatrix.cols << std::endl;
std::cout << cameraMatrix.at(0, 0) << " " << cameraMatrix.at(0, 1) << " " << cameraMatrix.at(0, 2) << std::endl;
std::cout << cameraMatrix.at(1, 0) << " " << cameraMatrix.at(1, 1) << " " << cameraMatrix.at(1, 2) << std::endl;
std::cout << cameraMatrix.at(2, 0) << " " << cameraMatrix.at(2, 1) << " " << cameraMatrix.at(2, 2) << std::endl;
cv::waitKey(0);
}
Python
#coding:utf-8
import cv2
import numpy as np
import glob
# 找棋盤格角點
# 閾值
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
#棋盤格模板規格
w = 9
h = 6
# 世界座標系中的棋盤格點,例如(0,0,0), (1,0,0), (2,0,0) ....,(8,5,0),去掉Z座標,記為二維矩陣
objp = np.zeros((w*h,3), np.float32)
objp[:,:2] = np.mgrid[0:w,0:h].T.reshape(-1,2)
# 儲存棋盤格角點的世界座標和影象座標對
objpoints = [] # 在世界座標系中的三維點
imgpoints = [] # 在影象平面的二維點
images = glob.glob('calib/*.png')
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 找到棋盤格角點
ret, corners = cv2.findChessboardCorners(gray, (w,h),None)
# 如果找到足夠點對,將其儲存起來
if ret == True:
cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
objpoints.append(objp)
imgpoints.append(corners)
# 將角點在影象上顯示
cv2.drawChessboardCorners(img, (w,h), corners, ret)
cv2.imshow('findCorners',img)
cv2.waitKey(1)
cv2.destroyAllWindows()
# 標定
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
# 去畸變
img2 = cv2.imread('calib/00169.png')
h, w = img2.shape[:2]
newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),0,(w,h)) # 自由比例引數
dst = cv2.undistort(img2, mtx, dist, None, newcameramtx)
# 根據前面ROI區域裁剪圖片
#x,y,w,h = roi
#dst = dst[y:y+h, x:x+w]
cv2.imwrite('calibresult.png',dst)
# 反投影誤差
total_error = 0
for i in xrange(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)
© 2020 GitHub, Inc.
寫了
5860316篇文章,獲得
23313次喜歡