Skip to content

Commit 745cbd0

Browse files
author
Thimoté Dupuch
committed
CPU imlementation for radialDistortion! with @tturbo
1 parent 341dd17 commit 745cbd0

File tree

4 files changed

+36
-23
lines changed

4 files changed

+36
-23
lines changed

Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "CameraModels"
22
uuid = "0d57b887-6120-40e6-8b8c-29d3116bc0c1"
3-
keywords = ["camera", "model", "pinhole", "distortion", "robotics", "images"]
3+
keywords = ["camera", "model", "pinhole", "distortion", "robotics", "images", "vision"]
44
version = "0.2.4"
55

66
[deps]
@@ -10,6 +10,7 @@ Manifolds = "1cead3c2-87b3-11e9-0ccd-23c62b72b94e"
1010
RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd"
1111
Rotations = "6038ab10-8711-5258-84ad-4b1120ba62dc"
1212
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
13+
# TODO : add LoopVectorization here
1314

1415
[compat]
1516
DocStringExtensions = "0.8, 0.9"

src/CameraModels.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ using StaticArrays
77
import Rotations as Rot_
88
import Base: getindex, getproperty, show
99
using RecursiveArrayTools: ArrayPartition
10+
using LoopVectorization: @tturbo
1011

1112
# exports
1213
include("ExportAPI.jl")

src/entities/CameraCalibration.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Notes
2222
- Common *camera-frame* in computer vision and robotics, `(x,y) <==> (width,height) <==> (j,i)`,
2323
- Using top left corner of image as `(0,0)` in all cases.
2424
- Direct comparison with [OpenCV convention](https://docs.opencv.org/3.4/d9/d0c/group__calib3d.html) is:
25-
- `(x,y) [CamXYZ] <==> (j,i) [Images.jl] <==> (u,v) [OpenCV]` -- look very carfully at `(u,v) <==> (j,i)` in *image-frame*
25+
- `(x,y) [CamXYZ] <==> (j,i) [Images.jl] <==> (u,v) [OpenCV]` -- look very carefully at `(u,v) <==> (j,i)` in *image-frame*
2626
- Always follow right hand rule for everything.
2727
- An abstract type [`AbstractCameraModel`](@ref) is provided to develop implementations against `struct` and `mutable struct` types.
2828
@@ -49,7 +49,7 @@ end
4949
"""
5050
$TYPEDEF
5151
52-
See [`CameraCalibraton`](@ref).
52+
See [`CameraCalibration`](@ref).
5353
"""
5454
Base.@kwdef mutable struct CameraCalibrationMutable{R <: Real, N} <: AbstractCameraModel
5555
""" number of pixels from top to bottom """

src/services/Utils.jl

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -51,37 +51,48 @@ yu = yc + (yd + yc) / (1 + K1*(r^2) + K2*(r^4) + ...)
5151
```
5252
5353
DevNotes (Contributions welcome):
54-
- TODO manage image clamping if `dest` is too small and data should be cropped out.
55-
- TODO buffer radii matrix for better reuse on repeat image size sequences
56-
- TODO dispatch with either CUDA.jl or AMDGPU.jl <:AbstractArray objects.
57-
- TODO use Tullio.jl with multithreading and GPU
58-
- TODO check if LoopVectorization.jl tools like `@avx` help performance
54+
- TODO : provide a GPU implementation
55+
-> either via dispatch with AMDGPU and CUDA (should be avoided)
56+
-> or using a vendor-agnostic code with KernelAbstractions.jl
5957
"""
6058
function radialDistortion!(
6159
cc::CameraCalibration{<:Real, N},
6260
dest::AbstractMatrix,
6361
src::AbstractMatrix
6462
) where {N}
65-
# loop over entire image
66-
for h_d in size(src, 1), w_d in size(src, 2)
67-
# temporary coordinates
68-
@inbounds h_ = h_d - cc.center[1]
69-
@inbounds w_ = w_d - cc.center[2]
70-
# calculate the radius from distortion center
71-
_radius2 = h_^2 + w_^2
72-
# calculate the denominator
73-
_denomin = 1
74-
@inbounds @fastmath for k in 1:N
75-
_denomin += cc.kc[k] * (_radius2^k)
63+
64+
center = SVector{2}(cc.center)
65+
k = ntuple(i -> cc.kc[i], N)
66+
H, W = size(src)
67+
c₁, c₂ = center
68+
69+
# pre-allocate buffers for the radius powers
70+
buf = Vector{T}(undef, max(H, W))
71+
72+
@tturbo for h_d in 1:H, w_d in 1:W
73+
h_ = h_d - c₁
74+
w_ = w_d - c₂
75+
= h_ * h_ + w_ * w_
76+
77+
num = one(T)
78+
rⁿ =
79+
@inbounds for i in 1:N
80+
num += k[i] * rⁿ
81+
rⁿ *=
7682
end
77-
# calculate the new 'undistorted' coordinates and set equal to incoming image
78-
@inbounds @fastmath h_u = cc.center[1] + h_ / _denomin
79-
@inbounds @fastmath w_u = cc.center[2] + h_ / _denomin
80-
dest[h_u, w_u] = src[h_d, w_d]
83+
84+
h_u = c₁ + h_ / num
85+
w_u = c₂ + w_ / num
86+
87+
# nearest-neighbour lookup (round + clamp)
88+
hi = clamp(round(Int, h_u), 1, H)
89+
wi = clamp(round(Int, w_u), 1, W)
90+
dest[h_d, w_d] = src[hi, wi]
8191
end
8292
return nothing
8393
end
8494

95+
8596
"""
8697
intersectLineToPlane3D(planenorm, planepnt, raydir, raypnt) -> point
8798

0 commit comments

Comments
 (0)