diff --git a/examples/threadcall_detect_in_image.jl b/examples/threadcall_detect_in_image.jl new file mode 100644 index 0000000..8ff20a5 --- /dev/null +++ b/examples/threadcall_detect_in_image.jl @@ -0,0 +1,56 @@ +using Images +#Additional required packages to run this example. +#Pkg.add("Images") + +using AprilTags + +# Simple method to show the image with the tags +function showImage(image, tags) + # Convert image to RGB + imageCol = RGB.(image) + #traw color box on tag corners + foreach(tag->drawTagBox!(imageCol, tag), tags) + imageCol +end + + +## +# Create default detector +detector = AprilTagDetector() + +#Run against a file +image = load(dirname(Base.source_path()) *"/../data/tagtest.jpg") + +@sync begin + starttime = Dates.value(now()) + #call detector in thread + @async global t1 = @timed begin + println("time before detector $(Dates.value(now())-starttime) ms") + global tags = AprilTags.threadcalldetect(detector, image) + # ↑ comment --- compare with this --- uncomment ↓ + # global tags = detector(image) + println("time after detector $(Dates.value(now())-starttime) ms") + + @show length(tags) + end + #carry on doing something else + @async global t2 = @timed begin + println("time starting other $(Dates.value(now())-starttime) ms") + imageCol = load(dirname(Base.source_path()) *"/../data/colortag.jpg") + A = randn(1000,1000) + randsum = sum(A*A') + println("time finished other $(Dates.value(now())-starttime) ms") + @show randsum + end +end + + println("time for detector: $(t1[2]) seconds") + println("time for other: $(t2[2]) seconds") + println() + +showImage(image, tags) + + + +## clean up detector once finished +freeDetector!(detector) diff --git a/src/helpers.jl b/src/helpers.jl index 065a2a6..304fc5e 100644 --- a/src/helpers.jl +++ b/src/helpers.jl @@ -84,6 +84,37 @@ function (detector::AprilTagDetector)(image::Array{ColorTypes.RGB{T}, 2}) where return detector(image) end +""" + threadcalldetect(detector, image) +Run the april tag detector on a image +""" +function threadcalldetect(detector::AprilTagDetector, image::Array{T, 2}) where T <: U8Types + + if detector.td == C_NULL + error("AprilTags Detector does not exist") + end + + if detector.tf == C_NULL + error("AprilTags family does not exist") + end + #create image8 object for april tags + image8 = convert(AprilTags.image_u8_t, image) + + # run detector on image + detections = threadcall_apriltag_detector_detect(detector.td, image8) + + # copy and return detections julia struct + tags = AprilTags.copyAprilTagDetections(detections) + # copy and return detections c struct + # tags = getTagDetections(detections) + + #distroy detections memmory + apriltag_detections_destroy(detections) + + return tags + +end + """ freeDetector!(apriltagdetector) Free the allocated memmory diff --git a/src/wrapper.jl b/src/wrapper.jl index 75b612a..235cadd 100644 --- a/src/wrapper.jl +++ b/src/wrapper.jl @@ -286,7 +286,7 @@ mutable struct apriltag_detector nquads::UInt32 tag_families::Ptr{zarray_t} wp::Ptr{workerpool_t} - + # mutex::pthread_mutex_t mutex::NTuple{40, UInt8} @@ -404,6 +404,18 @@ function apriltag_detector_detect(td, im_orig) ccall((:apriltag_detector_detect, :libapriltag), Ptr{zarray_t}, (Ptr{apriltag_detector_t}, Ptr{image_u8_t}), td, Ref(im_orig)) end +""" + threadcall_apriltag_detector_detect(tag_detector, image) +*Experimental* call apriltag_detector_detect in a seperate thread using the experimantal `@threadcall` +Detect tags from an image and return an array of apriltag_detection_t*. +You can use apriltag_detections_destroy to free the array and the detections it contains, or call +detection_destroy and zarray_destroy yourself. +""" +function threadcall_apriltag_detector_detect(td, im_orig) + @threadcall((:apriltag_detector_detect, :libapriltag), Ptr{zarray_t}, (Ptr{apriltag_detector_t}, Ptr{image_u8_t}), td, Ref(im_orig)) +end + + function apriltag_detection_destroy(det) ccall((:apriltag_detection_destroy, :libapriltag), Void, (Ptr{apriltag_detection_t},), det) end diff --git a/test/runtests.jl b/test/runtests.jl index 310fe51..842685a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -62,6 +62,9 @@ using Base.Test @test length(detector(gray.(image))) == 3 @test length(detector(reinterpret(UInt8,image))) == 3 + tagsth = AprilTags.threadcalldetect(detector, image) + @test length(tagsth) == 3 + #test on random image, should detect zero tags @test length(detector(rand(Gray{N0f8},100,100))) == 0 @@ -175,6 +178,7 @@ using Base.Test detector = AprilTagDetector() freeDetector!(detector) @test_throws ErrorException tags = detector(image) + @test_throws ErrorException tags = AprilTags.threadcalldetect(detector, image) @test_throws ErrorException AprilTags.setnThreads(detector, 4) @test_throws ErrorException AprilTags.setquad_decimate(detector, 1.0) @test_throws ErrorException AprilTags.setquad_sigma(detector,0.0) @@ -186,6 +190,7 @@ using Base.Test detector = AprilTagDetector() detector.tf = C_NULL @test_throws ErrorException tags = detector(image) + @test_throws ErrorException tags = AprilTags.threadcalldetect(detector, image) @test freeDetector!(detector) == nothing end