.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "MRGINGHAM 1" .TH MRGINGHAM 1 "2023-01-30" "mrgingham 1.22" "mrgingham: chessboard corner finder" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" mrgingham \- Extract chessboard corners from a set of images .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& $ mrgingham image*.jpg \& \& # filename x y level \& image1.jpg \- \- \& image2.jpg 1385.433000 1471.719000 0 \& image2.jpg 1483.597000 1469.825000 0 \& image2.jpg 1582.086000 1467.561000 1 \& ... \& \& \& $ mrgingham image.jpg | \& vnl\-filter \-p x,y,level | \& feedgnuplot \-\-domain \e \& \-\-with \*(Aqlinespoints pt 7 ps 2 palette\*(Aq \e \& \-\-tuplesizeall 3 \e \& \-\-image image.jpg \& \& [ image pops up with the detected grid plotted on top, detections color\-coded \& by their decimation level ] .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" The mrgingham tool detects chessboard corners from images stored on disk. The images are given on the commandline, as globs. Each glob is expanded, and each image is processed, possibly in parallel if \-j was given. .PP The output is a vnlog text table ( containing columns: .PP \&\- filename: path to the image on disk .PP \&\- x, y: detected pixel coordinates of the chessboard corner .PP \&\- level: image level used in detecting this corner. Level 0 means \&\*(L"full-resolution\*(R". Level 1 means \*(L"half-resolution\*(R" and that the noise on this detection has double the standard deviation. Level 2 means \*(L"quarter-resolution\*(R" and so on. .PP If no chessboard was found in an image, a single record is output: .PP .Vb 1 \& filename \- \- \- .Ve .PP The corners are output in a consistent order: starting at the top-left, traversing the grid, in the horizontal direction first. Usually, the chessboard is observed by multiple cameras mounted at a similar orientation, so this consistent order is consistent across cameras. .PP By default we look for a \s-1CHESSBOARD,\s0 not a grid of circles or Apriltags or anything else. By default we apply adaptive histogram equalization (\s-1CLAHE\s0), then blur with a radius of 1. We then use an adaptive level of downsampling when looking for the chessboard. These defaults work very well in practice. .PP For debugging, pass in \-\-debug. This will dump the various intermediate results into /tmp and it will report more stuff on the console. Most of the intermediate results are self-plotting data files. Run them. For debugging sequence candidates, pass in \-\-debug\-sequence x,y where 'x,y' are the approximate image coordinates of the start of a given sequence (corner on the edge of a chessboard. This doesn't need to be exact; mrgingham will report on the nearest corner .PP See the mrgingham project documentation for more detail: .PP .SH "OPTIONS" .IX Header "OPTIONS" .SS "\s-1POSITIONAL ARGUMENTS\s0" .IX Subsection "POSITIONAL ARGUMENTS" .Vb 2 \& imageglobs \& Globs specifying the images to process. May be given more than once .Ve .SS "\s-1OPTIONAL ARGUMENTS\s0" .IX Subsection "OPTIONAL ARGUMENTS" .Vb 10 \& \-\-blobs \& Finds circle centers instead of chessboard corners. Not recommended \& \-\-gridn N \& Requests detections of an NxN grid of corners. If omitted, N defaults to 10 \& \-\-noclahe \& Controls image preprocessing. Unless given, we will apply adaptive histogram \& equalization (CLAHE algorithm) to the images. This is EXTREMELY helpful if \& the images aren\*(Aqt illuminated evenly; which applies to most real\-world \& images. \& \-\-blur RADIUS \& Controls image preprocessing. Applies a gaussian blur to the image after the \& histogram equalization. A light blurring is very helpful with CLAHE, since \& it produces noisy images. By default we will blur with radius = 1. Set to <= \& 0 to disable \& \-\-level LEVEL \& Controls image preprocessing. Applies a downsampling to the image (after \& CLAHE and \-\-blur, if those are given). Level 0 means \*(Aquse the original \& image\*(Aq. Level > 0 means downsample by 2**level. Level < 0 means \*(Aqtry several \& different levels until we find one that works. This is the default. \& \-\-no\-refine \& Disables corner refinement. By default, the coordinates of reported corners \& are re\-detected at less\-downsampled zoom levels to improve their accuracy. \& If we do not want to do that, pass \-\-no\-refine \& \-\-jobs N \& Parallelizes the processing N\-ways. \-j is a synonym. This is just like GNU \& make, except you\*(Aqre required to explicitly specify a job count. \& \-\-debug \& If given, mrgingham will dump various intermediate results into /tmp and it \& will report more stuff on the console. The output is self\-documenting \& \-\-debug\-sequence \& If given, we report details about sequence matching. Do this if \-\-debug \& reports correct\-looking corners (all corners detected, no doubled\-up \& detections, no detections inside the chessboard but not on a corner) .Ve .SH "REPOSITORY" .IX Header "REPOSITORY" .SH "AUTHOR" .IX Header "AUTHOR" Dima Kogan, \f(CW\*(C`\*(C'\fR .SH "LICENSE AND COPYRIGHT" .IX Header "LICENSE AND COPYRIGHT" This library is free software; you can redistribute it and/or modify it under the terms of the \s-1GNU\s0 Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. .PP Copyright 2017\-2018 California Institute of Technology .PP Copyright 2017\-2018 Dima Kogan (\f(CW\*(C`dima@secretsauce.net\*(C'\fR)