Compare commits
5 Commits
54365ae058
...
de9483f562
Author | SHA1 | Date | |
---|---|---|---|
de9483f562 | |||
68820a5a36 | |||
90f54da7c5 | |||
b5f24d4fdf | |||
f967c089c0 |
45
.clang-format
Normal file
45
.clang-format
Normal file
@ -0,0 +1,45 @@
|
||||
BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: true
|
||||
PadOperators: true
|
||||
AlignConsecutiveDeclarations:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: true
|
||||
PadOperators: true
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine : Always
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
ColumnLimit: 100
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
Language: Cpp
|
||||
PointerAlignment: Right
|
||||
IndentWidth: 4
|
||||
MaxEmptyLinesToKeep: 1
|
||||
ObjCSpaceAfterProperty: true
|
||||
ObjCBlockIndentWidth: 4
|
||||
#AlignOperands: true
|
||||
SpacesInSquareBrackets: true
|
||||
SpacesInParentheses : false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpacesInContainerLiterals: true
|
||||
IndentWrappedFunctionNames: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
BreakConstructorInitializersBeforeComma: true
|
||||
SpaceAfterCStyleCast: false
|
||||
# SortIncludes: true
|
||||
IndentCaseLabels: true
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
30
.clang-tidy
Normal file
30
.clang-tidy
Normal file
@ -0,0 +1,30 @@
|
||||
Checks: '-*,bugprone-*,clang-*,cppcoreguidelines-*,hicpp-avoid-goto,hicpp-braces-around-statements,hicpp-deprecated-headers,hicpp-exception-baseclass,hicpp-explicit-conversions,hicpp-function-size,hicpp-invalid-access-moved,hicpp-member-init,hicpp-move-const-arg,hicpp-multiway-paths-covered,hicpp-named-parameter,hicpp-new-delete-operators,hicpp-no-*,hicpp-noexcept-move,hicpp-signed-bitwise,hicpp-special-member-functions,hicpp-static-assert,hicpp-undelegated-constructor,hicpp-uppercase-literal-suffix,hicpp-use-*,hicpp-vararg,misc-*,modernize-avoid-*,modernize-concat-nested-namespaces,modernize-deprecated-*,modernize-loop-convert,modernize-macro-to-enum,modernize-make-*,modernize-pass-by-value,modernize-raw-string-literal,modernize-redundant-void-arg,modernize-replace-*,modernize-return-braced-init-list,modernize-shrink-to-fit,modernize-unary-static-assert,modernize-use-auto,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-emplace,modernize-use-equals-*,modernize-use-nodiscard,modernize-use-noexcept,modernize-use-nullptr,modernize-use-override,modernize-use-transparent-functors,modernize-use-uncaught-exceptions,modernize-use-using,openmp-*,performance-*,readability-*'
|
||||
#WarningAsErrors: ''
|
||||
HeaderFilterRegex: ''
|
||||
AnalyzeTemporaryDtors: false
|
||||
FormatStyle: none
|
||||
CheckOptions:
|
||||
- key: readability-identifier-naming.VariableCase
|
||||
value: camelBack
|
||||
- key: readability-identifier-naming.MacroDefinitionCase
|
||||
value: UPPER_CASE
|
||||
- key: readability-identifier-naming.EnumCase
|
||||
value: UPPER_CASE
|
||||
- key: readability-identifier-naming.EnumConstantCase
|
||||
value: UPPER_CASE
|
||||
- key: readability-identifier-naming.GlobalVariableCase
|
||||
value: camelBack
|
||||
- key: readability-identifier-naming.GlobalVariablePrefix
|
||||
value: g
|
||||
- key: readability-identifier-naming.MemberCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.MemberPrefix
|
||||
value: m
|
||||
- key: readability-identifier-naming.ClassMemberCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.ClassMemberPrefix
|
||||
value: m
|
||||
- key: readability-identifier-naming.ClassCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.StructCase
|
||||
value: CamelCase
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
build
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "third_party/eigen"]
|
||||
path = third_party/eigen
|
||||
url = https://github.com/eigen-mirror/eigen.git
|
19
CMakeLists.txt
Normal file
19
CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
project(calib)
|
||||
|
||||
find_package(OpenCV REQUIRED)
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
main.cpp
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${OpenCV_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/third_party/eigen)
|
||||
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES})
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE IMG_DIR="${CMAKE_CURRENT_SOURCE_DIR}/img")
|
||||
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:/W4 /WX /external:W0>
|
||||
$<$<STREQUAL:${CMAKE_SYSTEM_NAME},Linux>:-fPIC -fvisibility=hidden -Wall -Wextra -Wpedantic -Wmisleading-indentation -Wunused -Wuninitialized -Wshadow -Wconversion -Werror>
|
||||
$<$<AND:$<CXX_COMPILER_ID:Clang>,$<STREQUAL:${CMAKE_SYSTEM_NAME},Windows>>:/W4 /WX /external:W0>
|
||||
)
|
||||
|
@ -1,3 +1,6 @@
|
||||
# camere_calib
|
||||
# camera calibration with one frame
|
||||
1. distortion
|
||||
2. perspective
|
||||
|
||||
camera calibration with one frame (distortion and perspective)
|
||||

|
||||

|
||||
|
BIN
img/src.bmp
Normal file
BIN
img/src.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 MiB |
BIN
img/wrap.jpg
Normal file
BIN
img/wrap.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 612 KiB |
182
main.cpp
Normal file
182
main.cpp
Normal file
@ -0,0 +1,182 @@
|
||||
#include <Eigen/Eigen>
|
||||
#include <iostream>
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
void transform(const std::vector<cv::Point3f> &src, std::vector<cv::Point3f> &dst,
|
||||
const cv::Mat &rvec, const cv::Mat &tvec) {
|
||||
cv::Mat r;
|
||||
cv::Rodrigues(rvec, r);
|
||||
|
||||
dst.clear();
|
||||
for (auto &pt : src) {
|
||||
cv::Mat point(3, 1, CV_64FC1);
|
||||
point.at<double>(0, 0) = pt.x;
|
||||
point.at<double>(1, 0) = pt.y;
|
||||
point.at<double>(2, 0) = pt.z;
|
||||
|
||||
cv::Mat rt = r * point + tvec;
|
||||
|
||||
dst.emplace_back(rt.at<double>(0, 0), rt.at<double>(1, 0), rt.at<double>(2, 0));
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
auto src = cv::imread(std::string(IMG_DIR) + "/src.bmp", cv::IMREAD_GRAYSCALE);
|
||||
if (src.empty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int width = 22;
|
||||
int height = 16;
|
||||
float gridSize = 1.f;
|
||||
cv::Size patternSize(width, height);
|
||||
|
||||
std::vector<cv::Point3f> obj;
|
||||
obj.reserve(width * height);
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
obj.emplace_back(x * gridSize, y * gridSize, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<cv::Point2f> corners;
|
||||
auto found = cv::findChessboardCornersSB(src, patternSize, corners);
|
||||
if (!found) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cv::Mat color;
|
||||
cv::cvtColor(src, color, cv::COLOR_GRAY2RGB);
|
||||
cv::drawChessboardCorners(color, patternSize, corners, found);
|
||||
// cv::imshow("pattern", color);
|
||||
|
||||
cv::Mat cameraMatrix;
|
||||
cv::Mat distCoeffs;
|
||||
std::vector<cv::Mat> tVecs;
|
||||
std::vector<cv::Mat> rVecs;
|
||||
|
||||
auto error = cv::calibrateCamera(std::vector<std::vector<cv::Point3f>>{obj},
|
||||
std::vector<std::vector<cv::Point2f>>{corners}, src.size(),
|
||||
cameraMatrix, distCoeffs, rVecs, tVecs);
|
||||
std::cout << "RMS re-projection error:" << error << std::endl;
|
||||
|
||||
std::cout << "camera matrix:\n"
|
||||
<< cameraMatrix << std::endl
|
||||
<< "dist coeff:\n"
|
||||
<< distCoeffs << std::endl
|
||||
<< "translate:\n"
|
||||
<< tVecs[ 0 ] << std::endl
|
||||
<< "rotation:\n"
|
||||
<< rVecs[ 0 ] << std::endl;
|
||||
|
||||
cv::Mat undistortImg;
|
||||
cv::undistort(src, undistortImg, cameraMatrix, distCoeffs);
|
||||
cv::imshow("dst", undistortImg);
|
||||
|
||||
cv::drawFrameAxes(color, cameraMatrix, distCoeffs, rVecs[ 0 ], tVecs[ 0 ], 10);
|
||||
cv::imshow("coord", color);
|
||||
|
||||
std::vector<cv::Point2f> pts;
|
||||
cv::undistortImagePoints(corners, pts, cameraMatrix, distCoeffs);
|
||||
|
||||
std::vector<cv::Point2f> obj2;
|
||||
obj2.reserve(width * height);
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
obj2.emplace_back(x * gridSize, y * gridSize);
|
||||
}
|
||||
}
|
||||
auto hom = cv::findHomography(pts, obj2, cv::RANSAC);
|
||||
|
||||
std::cout << "hom:\n" << hom << std::endl;
|
||||
|
||||
// image to pattern coord
|
||||
std::vector<cv::Point2f> origins{{0.f, 0.f},
|
||||
{(float)src.cols - 1, 0},
|
||||
{(float)src.cols - 1.f, (float)src.rows - 1.f},
|
||||
{0.f, (float)src.rows - 1.f},
|
||||
pts[ 0 ]};
|
||||
std::vector<cv::Point2f> perf;
|
||||
cv::perspectiveTransform(origins, perf, hom);
|
||||
|
||||
// pattern to camera coord
|
||||
std::vector<cv::Point3f> origins2{
|
||||
{perf[ 0 ].x, perf[ 0 ].y, 0.f},
|
||||
{perf[ 1 ].x, perf[ 1 ].y, 0.f},
|
||||
{perf[ 2 ].x, perf[ 2 ].y, 0.f},
|
||||
{perf[ 3 ].x, perf[ 3 ].y, 0.f},
|
||||
{0.f, 0.f, 0.f},
|
||||
{1.f, 0.f, 0.f},
|
||||
};
|
||||
std::vector<cv::Point3f> trans;
|
||||
transform(origins2, trans, rVecs[ 0 ], tVecs[ 0 ]);
|
||||
|
||||
auto offset0 = trans[ 1 ] - trans[ 0 ];
|
||||
Eigen::Vector3f v0(offset0.x, offset0.y, offset0.z);
|
||||
|
||||
auto offset1 = trans[ 3 ] - trans[ 0 ];
|
||||
Eigen::Vector3f v1(offset1.x, offset1.y, offset1.z);
|
||||
|
||||
Eigen::Vector3f v2 = v0.cross(v1).normalized();
|
||||
|
||||
Eigen::Vector3f v3(0.f, 0.f, 1.f);
|
||||
|
||||
auto rot = Eigen::Quaternionf::FromTwoVectors(v2, v3);
|
||||
|
||||
std::vector<cv::Point3f> rotated;
|
||||
Eigen::Vector3f p0(trans[ 0 ].x, trans[ 0 ].y, trans[ 0 ].z);
|
||||
for (auto &pt : trans) {
|
||||
Eigen::Vector3f point(pt.x, pt.y, pt.z);
|
||||
Eigen::Vector3f offset = point - p0;
|
||||
Eigen::Vector3f rotPt = rot * offset;
|
||||
Eigen::Vector3f p = rotPt + p0;
|
||||
|
||||
rotated.emplace_back(p.x(), p.y(), p.z());
|
||||
}
|
||||
|
||||
auto v00 = rotated[ 5 ] - rotated[ 4 ];
|
||||
auto v01 = Eigen::Vector3f(v00.x, v00.y, v00.z);
|
||||
auto v02 = Eigen::Vector3f(-1.f, 0.f, 0.f);
|
||||
auto rot2 = Eigen::Quaternionf::FromTwoVectors(v01, v02);
|
||||
|
||||
std::vector<cv::Point3f> rotated2;
|
||||
Eigen::Vector3f p00(rotated[ 0 ].x, rotated[ 0 ].y, rotated[ 0 ].z);
|
||||
for (auto &pt : rotated) {
|
||||
Eigen::Vector3f point(pt.x, pt.y, pt.z);
|
||||
Eigen::Vector3f offset = point - p00;
|
||||
Eigen::Vector3f rotPt = rot2 * offset;
|
||||
Eigen::Vector3f p = rotPt + p00;
|
||||
|
||||
rotated2.emplace_back(p.x(), p.y(), p.z());
|
||||
}
|
||||
|
||||
std::vector<cv::Point2f> projected;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
auto &pt = rotated2[ i ];
|
||||
cv::Mat point(3, 1, CV_64FC1);
|
||||
point.at<double>(0, 0) = pt.x;
|
||||
point.at<double>(1, 0) = pt.y;
|
||||
point.at<double>(2, 0) = pt.z;
|
||||
|
||||
cv::Mat proj = cameraMatrix * point;
|
||||
cv::Mat proj2 = proj / proj.at<double>(2, 0);
|
||||
projected.emplace_back(proj2.at<double>(0, 0), proj2.at<double>(1, 0));
|
||||
}
|
||||
|
||||
std::vector<cv::Vec2f> org;
|
||||
std::vector<cv::Vec2f> proj;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
auto &o = origins[ i ];
|
||||
auto &p = projected[ i ];
|
||||
|
||||
org.emplace_back(o.x, o.y);
|
||||
proj.emplace_back(p.x, p.y);
|
||||
}
|
||||
auto persperct = cv::getPerspectiveTransform(org, proj);
|
||||
|
||||
cv::Mat warpImg;
|
||||
cv::warpPerspective(undistortImg, warpImg, persperct, src.size(), cv::INTER_LINEAR);
|
||||
cv::imshow("warp", warpImg);
|
||||
|
||||
cv::waitKey();
|
||||
}
|
1
third_party/eigen
vendored
Submodule
1
third_party/eigen
vendored
Submodule
Submodule third_party/eigen added at 3147391d94
Reference in New Issue
Block a user