默认采用 OpenCV 相机坐标系(Z 朝前、Y 朝下),与 OpenGL/Blender 约定相反,需用 T_opencv_to_opengl 等函数转换;T 是 (4,4) 的 world-to-camera 矩阵,是 pose 的逆,且 t 形状为 (3,) 而非 (3,1);torch 相关功能(如图像指标)需额外安装 pip install camtools[torch]
camtools
yxlaoMIT更新放缓一套面向计算机视觉的相机工具集,用来处理相机内参、外参标定以及相机与激光雷达之间的坐标变换,方便做三维重建和多传感器对齐。
CamTools: Camera Tools for Computer Vision
pip install camtoolsREADME 未说明,未提及显存、GPU 型号或 CPU 运行要求
处理相机参数的工具库,统一做相机可视化、参数转换、投影与射线投射
一套面向计算机视觉的相机工具集,用来处理相机内参、外参标定以及相机与激光雷达之间的坐标变换,方便做三维重建和多传感器对齐。
核心能力
- 用 create_camera_frustums 可视化相机视锥,便于调试三维重建与 NeRF
- 在 T、pose、R/t、C、P 之间互相转换相机参数
- 把三维点投影到像素,并把深度图反投影回三维点
- 按相机参数对三角网格做射线投射生成深度图
- 图像与深度 I/O 强制类型和取值范围检查,避免 float/uint8、RGB/BGR 混淆
容易踩的坑
- v0.1.8v0.1.8 Release最新正式版2026-03-21 · 2026-03-21 18:55 UTC
Release v0.1.8
Pull Requests
- #94 ci: Replace formatter workflow with pre-commit lint
- #93 feat(compress_images): Add JPEG format support
- #92 feat(draw_bboxes): Interactive bbox with enlarged area
- #91 fix(crop_borders): Typo fix crop_boarders to crop_borders
- #90 feat(compress-images): Redesign
ct compress-imagescommand - #89 fix(camera.py): Modify assert_shape_ndim to match function signature
- #88 feat(project): Add points_to_depths function to calculate z-depths
- #87 docs(conf.py): Do not include git hash in docs for version-tagged commits
Features
JPEG Format Support (#93)
The
compress_imagestool now supports JPEG format in addition to PNG. Users can specify the output format via the new--formatoption.Interactive Bbox with Enlarged Area (#92)
The
draw_bboxestool now supports interactive bbox creation with an enlarged area for better usability.Redesigned compress-images Command (#90)
The
ct compress-imagescommand has been redesigned for improved CLI experience.points_to_depths Function (#88)
Added a new
points_to_depthsfunction in theprojectmodule to calculate z-depths from 3D points.Bug Fixes
- Fixed typo in
crop_bordersmodule name (crop_boarders→crop_borders) in #91 - Fixed
assert_shape_ndimfunction signature mismatch incamera.pyin #89
CI/CD Improvements
- Replaced formatter workflow with pre-commit lint configuration (#94)
- Added
.pre-commit-config.yamlfor consistent code quality checks across the project
Documentation
- Improved docs configuration to exclude git hash from version-tagged builds (#87)
Full Changelog: v0.1.7...v0.1.8
- v0.1.7v0.1.7 Release2025-01-11 · 2025-01-11 10:27 UTC
查看更新说明
CamTools v0.1.7 Release Notes
TL;DR
- CamTools's documentation website is now available at https://camtools.readthedocs.io/.
- Improved Open3D/NumPy version compatibility.
Summary
Docs: documentation improvements (#79, #80, #81, #82, #83, #84)
- Set up Sphinx documentation framework
- Configured Read the Docs hosting (https://camtools.readthedocs.io)
- Added GitHub Actions for documentation builds
- Improved docstrings across codebase
You can build the documentation locally with the following commands:
pip install -e .[docs] make -C docs clean && make -C docs html google-chrome docs/_build/html/index.htmlBuild: relax Open3D and NumPy version requirements (#85)
- Relaxed version requirements for Open3D and NumPy dependencies
- v0.1.6v0.1.6 Release2024-12-19 · 2024-12-19 06:03 UTC
查看更新说明
CamTools v0.1.6 Release Notes
Summary
Feature/Refactor: Standardized Depth Image and Distance Image Projection (#70)
- Terminology Clarification: Previously, the terms "depth" (z-depth) and "distance" (Euclidean distance between a 3D point and the camera center) were used interchangeably, leading to confusion. This release clarifies and standardizes the terminology to avoid ambiguity.
- Function Signatures: Use
im_depthorim_distancein function signatures to refer to depth images or distance images, respectively. - Conversion Functions: Added conversion functions between distance image and depth image:
ct.convert.im_distance_to_im_depthandct.convert.im_depth_to_im_distance.
Refactor: Jaxtyping annotation for select functions (#66, #68, #69, #70, #76)
- Now, some functions are annotated with e.g.,
points: Float[np.ndarray, "n 3"]to provide better syntax. - Full type annotation is planned in the future, along with a documentation website.
- Previously we considered adding a flexible backend with
ivyin this release, but it was canceled for simplicity.
Fix: Use numpy 1.x to Avoid Segfault with Open3D
- Issue: A segmentation fault occurs when using certain versions of Open3D with numpy 2.x. This issue is documented in Open3D issue #6840.
- Temporary Fix: This release restricts the use of numpy 1.x to avoid the segfault. This restriction will likely be removed in future releases when Open3D 0.19 is released, as per this comment.
API Changes
Added (or renamed as)
ct.raycast.mesh_to_im_depth: newct.raycast.mesh_to_im_depths: newct.raycast.mesh_to_im_distance: refactored to thisct.raycast.mesh_to_im_distances: refactored to thisct.convert.im_depth_to_im_distance: newct.convert.im_distance_to_im_depth: newct.convert.mesh_to_lineset: newct.solver.points_to_mesh_distances: newct.project.points_to_pixels: refactored to thisct.project.im_depth_to_point_cloud: refactored to this
Removed
ct.raycast.mesh_to_depthct.raycast.mesh_to_depthsct.project.point_cloud_to_pixelct.project.depth_to_point_cloud
- v0.1.5v0.1.5 Release2024-07-03 · 2024-07-03 07:48 UTC
查看更新说明
CamTools v0.1.5 Release Notes
The v0.1.5 release of CamTools brings a host of new features, significant improvements, and various fixes to enhance the overall functionality and usability of the library.
New Features and Improvements
- Render Geometries to Image: Introduced the ability to render geometries to an image with custom camera parameters, improving flexibility in rendering (#36).
- Line Radius in Render Geometries: Enabled
line_radiussupport inct.render.render_geometries()forLineSet, enhancing the visual representation of lines (#38). - Efficient Image Cropping: Enhanced the performance of image cropping, allowing for faster and more efficient operations (#39).
- Depth Image Rendering: Added
ct.render.render_geometriesfor rendering depth images, expanding the rendering capabilities (#57). - Image Scaling for Depth to Point Cloud: Added support for image scaling in
ct.project.depth_to_point_cloud(), allowing for more versatile image processing (#54). - Single Point Transformation: Introduced functionality to transform a single point, providing more precise control in point manipulation (#60).
Refactoring
- Consistent Terminology: Renamed up-down to top-bottom and ensured consistent use of
tblrthroughout the codebase (#42). - Master to Main Transition: Updated links and CI configurations to transition from
mastertomain, aligning with modern repository practices (#50). - Version Management: Switched to using
importlib.metadatafor version management for Python 3.8 and above, modernizing the build process (#51). - Projection API Enhancements: Improved projection APIs to enhance their functionality and usability (#53).
- Dependency Management: Removed
torchdependency, ensuring it is only installed for image metrics, reducing unnecessary dependencies (#55). - Depth to Point Cloud API Change: Renamed
return_as_imagetoto_imageindepth_to_point_cloud, making the function naming more intuitive (#58). - Utility Module Renaming: Renamed
ct.utilitytoct.util, streamlining the utility module structure (#45).
Fixes
- Order Preservation in Loops: Ensured order preservation for
mt_loopandmp_loop, improving consistency in processing (#44). - PNG Handling in Crop-Borders Tool: Improved the handling of PNG files with alpha channels in the crop-borders tool (#35).
- OpenCV and OpenGL Conversion: Fixed issues with transformations and pose conversions between OpenCV and OpenGL (#52).
- Device Assertion Removal: Removed the assertion for the same device, fixing potential issues related to device handling (#56).
Documentation and Build
- Contribution Section: Added a new contribution section to the documentation, encouraging community participation and providing guidelines for contributors (#40).
- Strict Editable Mode Installation: Updated installation instructions to include strict editable mode, ensuring a more reliable setup process (#48).
List of Changes
- add built-with-camtools badges in https://github.com/yxlao/camtools/pull/34
- fix: crop-boarders tool handle png with alpha channel in https://github.com/yxlao/camtools/pull/35
- new: render geometries to image with custom camera parameters in https://github.com/yxlao/camtools/pull/36
- new: extract rendering intrinsics (K) and extrinsics (T) set by Open3D in https://github.com/yxlao/camtools/pull/37
- new: support line_radius in ct.render.render_geometries() for LineSet in https://github.com/yxlao/camtools/pull/38
- perf: more efficient ct crop-boarders --same_crop in https://github.com/yxlao/camtools/pull/39
- docs: add contribution section in https://github.com/yxlao/camtools/pull/40
- feat: text renderer, artifact manager, image vstack in https://github.com/yxlao/camtools/pull/41
- refactor: rename up-down to top-bottom, use tblr consistently in https://github.com/yxlao/camtools/pull/42
- v0.1.4v0.1.4 Release2023-12-02 · 2023-12-02 14:10 UTC
查看更新说明
CamTools v0.1.4 Release Notes
The v0.1.4 release of CamTools introduces a range of new features, improvements, and fixes.
New Features and Improvements
- Up Triangle, Point-Plane Distance, Exact Camera Size: Introduced new camera frame functionalities including up triangle and point-plane distance calculation (#19).
- Camera Pose from Spherical Coordinate System: Added camera pose determination using spherical coordinates (#20).
- Command Line Tool for Image Compression: Added new command-line tool for efficient PNG and JPG image compression (#25).
- Improved Readme Graphics: Enhanced readme graphics for better visual appeal and information clarity (#30).
- CamTools Logo: Introduced a new visual identity with the CamTools logo (#29).
Refactoring
- Camera Frame Creation APIs: Refactored camera frame creation APIs to improve clarity and usability (#22).
- Project to Transform: Renamed
ct.project.homo_projecttoct.transform.transform_pointsfor better functional alignment (#23). - Normalization and Plot Module Changes: Moved functionalities from
ct.stattoct.normalizeand removedct.plotmodule (#24).
Fixes
- Handling Alpha PNGs and Avoiding Duplicated Compression: Improved handling of PNGs with alpha channels and optimized image compression process (#26).
- Continuous Integration and Tests: Addressed issues in CI and tests to ensure library stability and reliability (#28).
Automation
- Automatic PyPI Release Script: Streamlined PyPI release process with an automated script (#18).
For more details, visit the CamTools GitHub repository. Your feedback and contributions are welcome.
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
CamTools is a collection of tools for handling cameras in computer vision. It can be used for plotting, converting, projecting, ray casting, and doing more with camera parameters. It follows the standard camera coordinate system with clear and easy-to-use APIs.
What can you do with CamTools?
-
Plot cameras. Useful for debugging 3D reconstruction and NeRFs!
import camtools as ct import open3d as o3d cameras = ct.camera.create_camera_frustums(Ks, Ts) o3d.visualization.draw_geometries([cameras]) -
Convert camera parameters.
pose = ct.convert.T_to_pose(T) # Convert T to pose T = ct.convert.pose_to_T(pose) # Convert pose to T R, t = ct.convert.T_to_R_t(T) # Convert T to R and t C = ct.convert.pose_to_C(pose) # Convert pose to camera center K, T = ct.convert.P_to_K_T(P) # Decompose projection matrix P to K and T # And more... -
Projection and ray casting.
# Project 3D points to pixels. pixels = ct.project.points_to_pixel(points, K, T) # Back-project depth image to 3D points. points = ct.project.im_depth_to_points(im_depth, K, T) # Ray cast a triangle mesh to depth image given the camera parameters. im_depth = ct.raycast.mesh_to_im_depth(mesh, K, T, height, width) # And more... -
Image and depth I/O with no surprises.
Strict type checks and range checks are enforced. The image and depth I/O APIs are specifically designed to solve the following pain points:
- Is my image of type
float32oruint8? - Does it have range
[0, 1]or[0, 255]? - Is it RGB or BGR?
- Does my image have an alpha channel?
- When saving depth image as integer-based
.png, is it correctly scaled?
ct.io.imread() ct.io.imwrite() ct.io.imread_detph() ct.io.imwrite_depth() - Is my image of type
-
Command-line tools
ct(runs in terminal).# Crop image borders. ct crop-borders *.png --pad_pixel 10 --skip_cropped --same_crop # Draw synchronized bounding boxes interactively. ct draw-bboxes path/to/a.png path/to/b.png # For more command-line tools. ct --help -
And more.
- Solve line intersections.
- COLMAP tools.
- Points normalization.
- ...
Installation
To install CamTools, simply do:
pip install camtools
Alternatively, you can install CamTools from source with one of the following methods:
git clone https://github.com/yxlao/camtools.git
cd camtools
# Installation mode, if you want to use camtools only.
pip install .
# Editable mode, if you want to modify camtools on the fly.
pip install -e .
# Editable mode and dev dependencies.
pip install -e .[dev]
# Help VSCode resolve imports when installed with editable mode.
# https://stackoverflow.com/a/76897706/1255535
pip install -e .[dev] --config-settings editable_mode=strict
# Enable torch-related features (e.g. computing image metrics)
pip install camtools[torch]
# Enable torch-related features in editable mode
pip install -e .[torch]
Camera coordinate system
A homogeneous point [X, Y, Z, 1] in the world coordinate can be projected to a
homogeneous point [x, y, 1] in the image (pixel) coordinate using the
following equation:
$$ \lambda \left[\begin{array}{l} x \ y \ 1 \end{array}\right]=\left[\begin{array}{ccc} f_{x} & 0 & c_{x} \ 0 & f_{y} & c_{y} \ 0 & 0 & 1 \end{array}\right]\left[\begin{array}{llll} R_{00} & R_{01} & R_{02} & t_{0} \ R_{10} & R_{11} & R_{12} & t_{1} \ R_{20} & R_{21} & R_{22} & t_{2} \end{array}\right]\left[\begin{array}{c} X \ Y \ Z \ 1 \end{array}\right]. $$
We follow the standard OpenCV-style camera coordinate system as illustrated at the beginning of the README.
- Camera Coordinates: right-handed, with $Z$ pointing away from the camera
towards the view direction and $Y$ axis pointing down. Note that the OpenCV
convention (camtools' default) is different from the OpenGL/Blender
convention, where $Z$ points towards the opposite view direction, $Y$ points
up and $X$ points right. To convert between the OpenCV camera coordinates and
the OpenGL-style coordinates, use the conversion functions:
ct.convert.T_opencv_to_opengl()ct.convert.T_opengl_to_opencv()ct.convert.pose_opencv_to_opengl()ct.convert.pose_opengl_to_opencv()
- Image Coordinates: starts from the top-left corner of the image, with $x$
pointing right (corresponding to the image width) and $y$ pointing down
(corresponding to the image height). This is consistent with OpenCV. Pay
attention that the 0th dimension in the image array is the height (i.e., $y$)
and the 1st dimension is the width (i.e., $x$). That is:
- $x$ <=> $u$ <=> width <=> column <=> the 1st dimension
- $y$ <=> $v$ <=> height <=> row <=> the 0th dimension
K:(3, 3)camera intrinsic.K = [[fx, s, cx], [ 0, fy, cy], [ 0, 0, 1]]TorW2C:(4, 4)camera extrinsic.T = [[R | t = [[R00, R01, R02, t0], 0 | 1]] [R10, R11, R12, t1], [R20, R21, R22, t2], [ 0, 0, 0, 1]]Tis also known as the world-to-cameraW2Cmatrix, which transforms a point in the world coordinate to the camera coordinate.T's shape is(4, 4), not(3, 4).Tis the inverse ofpose, i.e.,np.linalg.inv(T) == pose.- The camera center
Cin world coordinate is projected to[0, 0, 0, 1]in camera coordinate.
R:(3, 3)rotation matrix.R = T[:3, :3]Ris a rotation matrix. It is an orthogonal matrix with determinant 1, as rotations preserve volume and orientation.R.T == np.linalg.inv(R)np.linalg.norm(R @ x) == np.linalg.norm(x), wherexis a(3,)vector.
t:(3,)translation vector.t = T[:3, 3]t's shape is(3,), not(3, 1).
poseorC2W:(4, 4)camera pose. It is the inverse ofT.poseis also known as the camera-to-worldC2Wmatrix, which transforms a point in the camera coordinate to the world coordinate.poseis the inverse ofT, i.e.,pose == np.linalg.inv(T).
C: camera center.C = pose[:3, 3]C's shape is(3,), not(3, 1).Cis the camera center in world coordinate. It is also the translation vector ofpose.
P:(3, 4)the camera projection matrix.Pis the world-to-pixel projection matrix, which projects a point in the homogeneous world coordinate to the homogeneous pixel coordinate.Pis the product of the intrinsic and extrinsic parameters.# P = K @ [R | t] P = K @ np.hstack([R, t[:, None]])P's shape is(3, 4), not(4, 4).- It is possible to decompose
Pinto intrinsic and extrinsic matrices by QR decomposition. - Don't confuse
Pwithpose. Don't confusePwithT.
- For more details, please refer to the following blog posts: part 1, part 2, and part 3.
Building Documentation
To build and view the documentation locally:
# Install documentation dependencies
pip install -e .[docs]
# Build the documentation
make -C docs clean && make -C docs html
# (Optional) Build the documentation with warnings as errors
make -C docs clean && make -C docs html SPHINXOPTS="-W --keep-going"
# Start a local server to view the documentation
python -m http.server 8000 --directory docs/_build/html
Then open your browser and navigate to http://localhost:8000 to view the documentation.
The documentation is also automatically built by GitHub Actions on pull requests and pushes to main. After merging to main, you can view:
- Public documentation at https://camtools.readthedocs.io/en/latest/
- Admin panel at https://app.readthedocs.org/projects/camtools/
Contributing
- Follow Angular's commit message convention for PRs.
- This applies to PR's title and ultimately the commit messages in
main. - The prefix shall be one of
build,ci,docs,feat,fix,perf,refactor,test. - Use lowercase.
- This applies to PR's title and ultimately the commit messages in
- See :doc:
contributing <contributing>for code formatting and pre-commit setup.
Build with CamTools
If you use CamTools in your project, consider adding one of the following badges to your project.