diff --git a/test/Project.toml b/test/Project.toml index 47b270c..027bfc2 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -3,5 +3,7 @@ Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" LazyArtifacts = "4af54fe1-eca0-43a8-85a7-787d91b784e3" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" OpenCV = "f878e3a2-a245-4720-8660-60795d644f2a" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +XML = "72c71f33-b9b6-44de-8c94-c961784809e2" diff --git a/test/runtests.jl b/test/runtests.jl index 08c1515..6160c43 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,6 +3,8 @@ using LazyArtifacts using OpenCV using FileIO using Test +using XML +using LinearAlgebra if "OPENCV_TEST_DATA_PATH" in keys(ENV) test_dir = joinpath(ENV["OPENCV_TEST_DATA_PATH"], "cv") @@ -18,4 +20,5 @@ end include("test_objdetect.jl") include("test_dnn.jl") include("test_fileio.jl") + include("test_corner_detection.jl") end diff --git a/test/test_corner_detection.jl b/test/test_corner_detection.jl new file mode 100644 index 0000000..ba71c93 --- /dev/null +++ b/test/test_corner_detection.jl @@ -0,0 +1,66 @@ +const Point = Tuple{Float32, Float32} # just for conviniencve + +function detect_corners(file, n_corners) + img = load(file) + gry = img[1:1, :, :] + ret, cv_corners = OpenCV.findChessboardCorners(gry, OpenCV.Size{Int32}(n_corners...)) + corners = reshape(Point.(eachslice(cv_corners, dims = 3)), n_corners) + return corners +end + +function parse_corners_file(file) + open(file, "r") do o + readuntil(o, "rows:") + rows = parse(Int, readuntil(o, "\n")) + readuntil(o, "cols:") + cols = parse(Int, readuntil(o, "\n")) + readuntil(o, "[") + txt = readuntil(o, "]") + num = parse.(Float32, split(txt, ',')) + corners = reverse(permutedims(Point.(eachslice(reshape(num, 2, cols, rows), dims=(2,3)))); dims = 1) + return corners, (rows, cols) + end +end + +function get_list(file) + doc = read(file, LazyNode) + str = filter(≠('"'), simple_value(doc[end][end])) + list = Dict{String, String}() + for line in split(str, '\n') + img_file, data_file = split(line) + list[img_file] = data_file + end + return list +end + +function calc_error(ps1, ps2) + s = 0.0 + for (p1, p2) in zip(ps1, ps2) + s += LinearAlgebra.norm_sqr(p1 .- p2) + end + sqrt(s/length(ps1)) +end + +function calc_error(img_file::AbstractString, data_file::AbstractString) + corners, n_corners = parse_corners_file(data_file) + detected_corners = detect_corners(img_file, n_corners) + calc_error(corners, detected_corners) +end + +@testset "detecting corners" begin + + path = joinpath(test_dir, "cameracalibration") + list = get_list(joinpath(path, "chessboard_list.dat")) + + k, v = first(list) + calc_error(joinpath(path, k), joinpath(path, v)) # why do we need this? + + @testset "in $k" for (k, v) in list + + img_file = joinpath(path, k) + data_file = joinpath(path, v) + + @test calc_error(img_file, data_file) < 2 + + end +end