Compare commits

...

5 Commits

Author SHA1 Message Date
de9483f562 Merge romote branch 'main' 2025-06-10 22:56:09 +08:00
68820a5a36 add depends Eigen 2025-06-10 22:46:18 +08:00
90f54da7c5 add readme 2025-06-10 22:35:21 +08:00
b5f24d4fdf add image 2025-06-10 22:31:56 +08:00
f967c089c0 misc 2025-06-07 09:50:21 +08:00
10 changed files with 286 additions and 2 deletions

45
.clang-format Normal file
View 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
View 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
View File

@ -0,0 +1 @@
build

3
.gitmodules vendored Normal file
View 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
View 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>
)

View File

@ -1,3 +1,6 @@
# camere_calib
# camera calibration with one frame
1. distortion
2. perspective
camera calibration with one frame (distortion and perspective)
![src](img/src.bmp)
![dst](img/wrap.jpg)

BIN
img/src.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 MiB

BIN
img/wrap.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 KiB

182
main.cpp Normal file
View 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

Submodule third_party/eigen added at 3147391d94