diff --git a/REQUIRE b/REQUIRE index 26da1fa..347f335 100644 --- a/REQUIRE +++ b/REQUIRE @@ -2,5 +2,3 @@ julia 0.7 Colors FixedPointNumbers ImageDraw -#Images -#ImageMagick diff --git a/docs/src/func_ref.md b/docs/src/func_ref.md index 0eb1c88..654d934 100644 --- a/docs/src/func_ref.md +++ b/docs/src/func_ref.md @@ -13,6 +13,8 @@ AprilTags.freeDetector! homography_to_pose drawTagBox! drawTagAxes! +getAprilTagImage +threadcalldetect ``` ### Wrappers ```@docs @@ -21,7 +23,7 @@ tag36h11_create tag36h11_destroy apriltag_detector_add_family apriltag_detector_detect -getAprilTagImage +threadcall_apriltag_detector_detect ``` ## Index diff --git a/docs/src/index.md b/docs/src/index.md index ae80225..60bd5ea 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -27,21 +27,34 @@ Initialize a detector with the default (tag36h11) tag family. # Create default detector detector = AprilTagDetector() ``` -Some tag detector parameters can be set at this time. +The tag detector parameters can be set as shown bellow. The default parameters are the recommended starting point. ```julia -AprilTags.setnThreads(detector, 4) -AprilTags.setquad_decimate(detector, 1.0) -AprilTags.setquad_sigma(detector,0.0) -AprilTags.setrefine_edges(detector,1) -AprilTags.setrefine_decode(detector,0) -AprilTags.setrefine_pose(detector,0) +detector.nThreads = 4 #number of threads to use +detector.quad_decimate = 1.0 #"Decimate input image by this factor" +detector.quad_sigma = 0.0 #"Apply low-pass blur to input; negative sharpens" +detector.refine_edges = 1 #"Set to 1 to spend more time to align edges of tags" +detector.refine_decode = 0 #"Set to 1 to spend more time to decode tags" +detector.refine_pose = 0 #"Set to 1 to spend more time to precisely localize tags" ``` -Increase the image decimation if faster processing is required; the -trade-off is a slight decrease in detection range. A factor of 1.0 -means the full-size input image is used. -Some Gaussian blur (quad_sigma) may help with noisy input images. +#### quad_decimate +Detection of quads can be done on a lower-resolution image, improving speed at a cost of pose accuracy and a slight decrease in detection rate. Decoding the binary payload is still done at full resolution. +Increase the image decimation if faster processing is required. A factor of 1.0 means the full-size input image is used. + +#### quad_sigma +What Gaussian blur should be applied to the segmented image (used for quad detection?). +Parameter is the standard deviation in pixels. Very noisy images benefit from non-zero values (e.g. 0.8). + +#### refine_edges +When non-zero, the edges of the each quad are adjusted to "snap to" strong gradients nearby. This is useful when decimation is employed, as it can increase the quality of the initial quad estimate substantially. Generally recommended to be on (1). Very computationally inexpensive. Option is ignored if quad_decimate = 1. + +#### refine_decode +When non-zero, detections are refined in a way intended to increase the number of detected tags. Especially effective for very small tags near the resolution threshold (e.g. 10px on a side). + +#### refine_pose +When non-zero, detections are refined in a way intended to increase the accuracy of the extracted pose. This is done by maximizing the contrast around the black and white border of the tag. This generally increases the number of successfully detected tags, though not as effectively (or quickly) as refine_decode. +This option must be enabled in order for "goodness" to be computed. ### Detection Process an input image and return a vector of detections. @@ -57,6 +70,13 @@ The caller is responsible for freeing the memmory by calling freeDetector!(detector) ``` +### Creating the AprilTag Images +The AprilTag images can be created using the `getAprilTagImage` function. +Eg. to create a tag image with id 1 from family 'tag36h11' run: +```julia +getAprilTagImage(1, AprilTags.tag36h11) +``` + ## Manual Outline ```@contents Pages = [ diff --git a/examples/detect_in_image.jl b/examples/detect_in_image.jl index 8c9e6fd..901f973 100644 --- a/examples/detect_in_image.jl +++ b/examples/detect_in_image.jl @@ -28,11 +28,11 @@ K = [fx 0 cx; detector = nothing try # Create default detector - detector = AprilTagDetector() + global detector = AprilTagDetector() # 1. Run against a file - image = load(dirname(Base.source_path()) *"/../data/tagtest.jpg") - tags = detector(image) + global image = load(dirname(Base.source_path()) *"/../data/tagtest.jpg"); + global tags = detector(image) showImage(image, tags, K) # 2. Run against an image from memory @@ -55,21 +55,21 @@ tf = nothing try # 3. Use low-level methods and direct access to wrapper - image = load(dirname(Base.source_path()) *"/../data/tagtest.jpg") + global image = load(dirname(Base.source_path()) *"/../data/tagtest.jpg") # Create april tag detector - td = apriltag_detector_create() + global td = apriltag_detector_create() # Create tag family - tf = tag36h11_create() + global tf = tag36h11_create() # add family to detector apriltag_detector_add_family(td, tf) # create image8 object for april tags image8 = convert(AprilTags.image_u8, image) # run detector on image - detections = apriltag_detector_detect(td, image8) + global detections = apriltag_detector_detect(td, image8) # copy detections - tags = getTagDetections(detections) + global tags = getTagDetections(detections) # Reading homography of tag 1 (deepcopy since memory is destoyed by c) - voidpointertoH = Base.unsafe_convert(Ptr{Void}, tags[1].H) + voidpointertoH = Base.unsafe_convert(Ptr{Nothing}, tags[1].H) # pointer to H matrix nrows = unsafe_load(Ptr{UInt32}(voidpointertoH),1) ncols = unsafe_load(Ptr{UInt32}(voidpointertoH),2) diff --git a/examples/threadcall_detect_in_image.jl b/examples/threadcall_detect_in_image.jl index 8ff20a5..1b97475 100644 --- a/examples/threadcall_detect_in_image.jl +++ b/examples/threadcall_detect_in_image.jl @@ -3,6 +3,7 @@ using Images #Pkg.add("Images") using AprilTags +using Dates # Simple method to show the image with the tags function showImage(image, tags) @@ -26,7 +27,7 @@ image = load(dirname(Base.source_path()) *"/../data/tagtest.jpg") #call detector in thread @async global t1 = @timed begin println("time before detector $(Dates.value(now())-starttime) ms") - global tags = AprilTags.threadcalldetect(detector, image) + global tags = threadcalldetect(detector, image) # ↑ comment --- compare with this --- uncomment ↓ # global tags = detector(image) println("time after detector $(Dates.value(now())-starttime) ms") @@ -37,7 +38,7 @@ image = load(dirname(Base.source_path()) *"/../data/tagtest.jpg") @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) + A = randn(2000,2000) randsum = sum(A*A') println("time finished other $(Dates.value(now())-starttime) ms") @show randsum diff --git a/src/AprilTags.jl b/src/AprilTags.jl index 2e88b61..587538b 100644 --- a/src/AprilTags.jl +++ b/src/AprilTags.jl @@ -17,6 +17,8 @@ AprilTagDetector, freeDetector!, getTagDetections, homography_to_pose, +threadcalldetect, +getAprilTagImage, # wrappers apriltag_detector_create, @@ -27,8 +29,7 @@ apriltag_detector_add_family, apriltag_detector_detect, apriltag_detections_destroy, apriltag_detector_destroy, - -getAprilTagImage, +threadcall_apriltag_detector_detect, #drawing and plotting drawTagBox!, diff --git a/test/REQUIRE b/test/REQUIRE index d7a4c2d..4736d2b 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -1,5 +1,5 @@ julia 0.7 -ImageCore -FileIO -ImageMagick +ImageCore 0.7.1 +FileIO 1.0.1 +ImageMagick 0.7 ImageDraw