Skip to content

Commit 45f3528

Browse files
authored
Merge pull request #960 from JuliaRobotics/23Q2/enh/features
adding image features
2 parents 1aafd2f + 945c351 commit 45f3528

File tree

8 files changed

+166
-19
lines changed

8 files changed

+166
-19
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@ Unmarshal = "cbff2730-442d-58d7-89d1-8e530c41eb02"
5757
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"
5858

5959
[compat]
60-
ApproxManifoldProducts = "0.6"
60+
ApproxManifoldProducts = "0.6, 0.7"
6161
AprilTags = "0.8, 0.9"
6262
Colors = "0.12"
6363
ColorVectorSpace = "0.9"
6464
Combinatorics = "1"
6565
CoordinateTransformations = "0.5, 0.6"
6666
DataStructures = "0.17, 0.18"
67-
DistributedFactorGraphs = "0.20.1"
67+
DistributedFactorGraphs = "0.20.1, 0.21"
6868
Distributions = "0.25"
6969
DocStringExtensions = "0.8, 0.9"
7070
FFTW = "1"

src/3rdParty/_PCL/_PCL.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import Base: getindex, setindex!, resize!, cat, convert, sizeof, hasproperty, ge
3737

3838
# gets overloaded
3939
import Manifolds: apply
40+
import DistributedFactorGraphs: packBlob, unpackBlob
4041
import IncrementalInference: ArrayPartition
4142

4243
## hold off on exports, users can in the mean-time use/import via e.g. _PCL.PointXYZ

src/3rdParty/_PCL/services/PointCloud.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,4 +483,6 @@ Base.show(io::IO, ::MIME"application/prs.juno.inline", pc::PointCloud) = show(io
483483

484484

485485

486+
487+
486488
#

src/3rdParty/_PCL/services/PointCloudUtils.jl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,38 @@ export findObjectVariablesFromWorld, previewObjectSubcloudInLocalFromWorld
44
export calcAxes3D
55

66

7+
8+
## Special case for LIDAR
9+
#FIXME convert to type save("pc.las", pc) supports and use pack unpack Blob
10+
function DistributedFactorGraphs.packBlob(::Type{format"LAS"}, pointCloud::_PCL.PointCloud)
11+
mimetype = "application/octet-stream; ext=las"
12+
io = IOBuffer()
13+
_PCL.saveLAS(Stream{format"LAS"}(io), pointCloud)
14+
blob = take!(io)
15+
return blob, mimetype
16+
end
17+
18+
function DistributedFactorGraphs.unpackBlob(::Type{format"LAS"}, blob::Vector{UInt8})
19+
io = IOBuffer(blob)
20+
ioStr = Stream{format"LAS"}(io)
21+
pc = _PCL.loadLAS(ioStr)
22+
return pc
23+
end
24+
25+
26+
function getPointCloud(fg::AbstractDFG, vlbl::Symbol, entry_label::Symbol)
27+
entry, blob = getData(fg, vlbl, entry_label)
28+
return unpackBlob(MIME(entry.mimeType), blob)
29+
end
30+
31+
32+
function getPointCloud_prepPoints(fg, vlbl, entry_label; minrange=0.0, maxrange=999.0)
33+
pc = getPointCloud(fg, vlbl, entry_label)
34+
return _PCL._prepPointCloud(pc; minrange, maxrange)
35+
end
36+
37+
38+
739
function getDataPointCloud(
840
nfg::AbstractDFG,
941
varlbl,

src/ExportAPI.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,5 @@ export
4949
SASDebug
5050

5151
export calcPointsInPoly
52-
export inside, AxisAlignedBoundingBox, OrientedBoundingBox
52+
export inside, AxisAlignedBoundingBox, OrientedBoundingBox
53+
export packBlob, unpackBlob

src/images/imagedata.jl

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,38 @@ DevNotes
1818
1919
See also: [`makeImage`](@ref)
2020
"""
21-
function toFormat(format::DataType,
22-
img::AbstractMatrix{<:Colorant} )
21+
function toFormat(
22+
format::Type{format"PNG"},
23+
img::AbstractMatrix{<:Colorant}
24+
)
2325
#
2426
io = IOBuffer()
2527
pngSm = Stream(format, io)
2628
save(pngSm, img) # think FileIO is required for this
2729
take!(io)
2830
end
2931

30-
toFormat(img::AbstractMatrix{<:Colorant}) = toFormat(format"PNG", img)
31-
32+
@deprecate toFormat(img::AbstractMatrix{<:Colorant}) toFormat(format"PNG", img)
33+
34+
35+
## Using default FileIO together with ImageIO
36+
# function DistributedFactorGraphs.packBlob(
37+
# fmt::Type{format"PNG"},
38+
# img::Union{<:AbstractMatrix{<:Colorant},<:AbstractMatrix{UInt8}}
39+
# )
40+
# blob = toFormat(fmt, img)
41+
# mimetype = "image/png"
42+
# return blob, mimetype
43+
# end
44+
# function DistributedFactorGraphs.unpackBlob(
45+
# ::Type{format"PNG"},
46+
# blob::Vector{UInt8}
47+
# )
48+
# io = IOBuffer(blob)
49+
# ioStr = Stream{format"PNG"}(io)
50+
# return load(ioStr)
51+
# # ImageMagick.readblob(imgBytes)
52+
# end
3253

3354
"""
3455
$SIGNATURES

src/images/imagedraw.jl

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,23 @@ using .ImageDraw
55
using .Colors
66

77
export makeImage!
8+
export drawKeypointsAndMask
89

910

10-
function makeImage!(pc::Caesar._PCL.PointCloud,
11-
x_domain::Tuple{<:Real,<:Real}=(-1000,1000),
12-
y_domain::Tuple{<:Real,<:Real}=x_domain;
13-
pose=nothing,
14-
ppose=nothing,
15-
rows::Integer=1000,
16-
cols::Integer=rows,
17-
color::C=Gray(0.1),
18-
trajCol=Gray(1.0),
19-
img::AbstractMatrix{<:Colorant} = Gray.(zeros(rows,cols)),
20-
circle_size::Real=1,
21-
drawkws... ) where {C <: Colorant}
11+
function makeImage!(
12+
pc::Caesar._PCL.PointCloud,
13+
x_domain::Tuple{<:Real,<:Real}=(-1000,1000),
14+
y_domain::Tuple{<:Real,<:Real}=x_domain;
15+
pose=nothing,
16+
ppose=nothing,
17+
rows::Integer=1000,
18+
cols::Integer=rows,
19+
color::C=Gray(0.1),
20+
trajCol=Gray(1.0),
21+
img::AbstractMatrix{<:Colorant} = Gray.(zeros(rows,cols)),
22+
circle_size::Real=1,
23+
drawkws...
24+
) where {C <: Colorant}
2225
#
2326

2427
x_range = (x_domain[2]-x_domain[1])
@@ -49,3 +52,21 @@ function makeImage!(pc::Caesar._PCL.PointCloud,
4952

5053
return img
5154
end
55+
56+
57+
function drawKeypointsAndMask(
58+
img::AbstractMatrix,
59+
keypoints::AbstractVector{<:CartesianIndex},
60+
mask::AbstractMatrix;
61+
markerColor::AbstractRGB=RGB{N0f8}(1,0,0),
62+
markerSize::Int = 20,
63+
)
64+
cimgA_ = applyMaskImage(img, mask)
65+
cimgA = convert.(RGB{N0f8}, cimgA_)
66+
67+
for ret_ in keypoints
68+
draw!(cimgA, Cross(Point(ret_.I[2], ret_.I[1]), markerSize), markerColor)
69+
end
70+
71+
return cimgA
72+
end

src/images/images.jl

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@
66

77
using ColorVectorSpace
88
using .Images
9+
import .GeoPr
10+
# import GeometricalPredicates as GeoPr
911

1012
export applyMaskImage
13+
export makeMaskImage
14+
export makeMaskImages
1115
export imhcatPretty
1216

1317
"""
@@ -36,6 +40,71 @@ function toImage(msgd::Dict{String,Any})
3640
end
3741
end
3842

43+
function makeMaskImage(
44+
img::AbstractMatrix,
45+
nodes::AbstractVector = [
46+
(180.0, 0.0); # ll
47+
(10.0, 600.0); # lr
48+
(0.0, 600.0); # ur
49+
(0.0, 0.0); # ul
50+
],
51+
)
52+
h,w = size(img)
53+
# h,w = 400,640
54+
buffer = zeros(UInt8, h, w)
55+
56+
points = []
57+
for nd in nodes
58+
push!(points, GeoPr.Point(nd...))
59+
end
60+
# (ll,lr,ur,ul)
61+
poly = GeoPr.Polygon(points...)
62+
63+
# populate buffer
64+
for x in collect(1:1:h), y in collect(1:1:w)
65+
if GeoPr.inpolygon(poly, GeoPr.Point(x, y))
66+
buffer[x, y] = UInt8(1)
67+
end
68+
end
69+
70+
return buffer, poly
71+
end
72+
73+
74+
"""
75+
$SIGNATURES
76+
77+
78+
```julia
79+
jstr_Mask_BOT = \"""
80+
[
81+
[[180.0,0.0],[10.0,600.0],[0.0,600.0],[0.0,0.0]],
82+
[[400.0,0.0],[400.0,640.0],[310.0,640.0],[315.0,165.0],[360.0,0.0],[399.0,0.0]]
83+
]
84+
\"""
85+
86+
mnodes = JSON3.read(jstr_Mask_BOT)
87+
mask_u8, polys = makeMaskImages(img, mnodes)
88+
```
89+
"""
90+
function makeMaskImages(
91+
img::AbstractMatrix,
92+
mnodes::AbstractVector{<:AbstractVector}
93+
)
94+
mask = zeros(UInt8, size(img)...)
95+
polys = []
96+
97+
for nodes in mnodes
98+
@show nodes
99+
mk, poly = makeMaskImage(img, nodes)
100+
mask += mk
101+
push!(polys, poly)
102+
end
103+
104+
return mask, polys
105+
end
106+
107+
39108
"""
40109
$SIGNATURES
41110

0 commit comments

Comments
 (0)