Simon Silk http://simonsilk.com/rss.xml en Processing a Text File in Perl http://simonsilk.com/blog-entry/2018-nov/processing-text-file-perl <span class="field field--name-title field--type-string field--label-hidden">Processing a Text File in Perl</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Loading a text, processing the contents, and outputting a processed verssion of the file is a common task in Perl.</p> <p>Sometimes it's light processing: rearrange the order of parts of each line. Sometime's it's heavier processing: collect a bunch of statistical data from the file and output a summary of the data with averages, mins, maxes, etc. In either case the following template is a handy starting point that shows the loading, some light processing, and writing the results to the output file. </p> <p></p><div class="geshifilter"><pre class="perl geshifilter-perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># Read in a file, process and optionally modify </span> <span style="color: #666666; font-style: italic;"># each line, saving results to a new file.</span> <span style="color: #666666; font-style: italic;"># Sample usage:</span> <span style="color: #666666; font-style: italic;"># perl process.pl input.csv </span> <span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span>   <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$infilename</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$ARGV</span><span style="color: #009900;">[</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">]</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;"># Open input file for reading</span> <a href="http://perldoc.perl.org/functions/open.html"><span style="color: #000066;">open</span></a><span style="color: #009900;">(</span><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$infh</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">'&lt;:encoding(UTF-8)'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$infilename</span><span style="color: #009900;">)</span> <span style="color: #b1b100;">or</span> <a href="http://perldoc.perl.org/functions/die.html"><span style="color: #000066;">die</span></a> <span style="color: #ff0000;">"Could not open file '$infilename' $!"</span><span style="color: #339933;">;</span>   <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$outfilename</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'output.csv'</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;"># Open output file for writing</span> <a href="http://perldoc.perl.org/functions/open.html"><span style="color: #000066;">open</span></a><span style="color: #009900;">(</span><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$outfh</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">'&gt;'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$outfilename</span><span style="color: #009900;">)</span> <span style="color: #b1b100;">or</span> <a href="http://perldoc.perl.org/functions/die.html"><span style="color: #000066;">die</span></a> <span style="color: #ff0000;">"Could not open file '$outfilename' $!"</span><span style="color: #339933;">;</span>   <span style="color: #b1b100;">while</span> <span style="color: #009900;">(</span><span style="color: #339933;">&lt;</span><span style="color: #0000ff;">$infh</span><span style="color: #339933;">&gt;</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span> <span style="color: #666666; font-style: italic;"># Iterate through the input file </span>   <span style="color: #0000ff;">$_</span> <span style="color: #339933;">=~</span> <span style="color: #009966; font-style: italic;">s/\R//</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;"># Remove linebreaks </span>   <span style="color: #666666; font-style: italic;"># Add you own per-line processing here...</span> <span style="color: #666666; font-style: italic;"># For example,</span> <span style="color: #b1b100;">if</span><span style="color: #009900;">(</span><span style="color: #009966; font-style: italic;">/\d+/</span><span style="color: #009900;">)</span><span style="color: #009900;">{</span> <span style="color: #666666; font-style: italic;"># if line contains number, modify and output to file</span> <a href="http://perldoc.perl.org/functions/print.html"><span style="color: #000066;">print</span></a> <span style="color: #0000ff;">$outfh</span> <span style="color: #ff0000;">"Line with number: $_<span style="color: #000099; font-weight: bold;">\n</span>"</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;"># </span> <span style="color: #009900;">}</span> <span style="color: #b1b100;">else</span><span style="color: #009900;">{</span> <span style="color: #666666; font-style: italic;"># otherwise, modify it a different way</span> <a href="http://perldoc.perl.org/functions/print.html"><span style="color: #000066;">print</span></a> <span style="color: #0000ff;">$outfh</span> <span style="color: #ff0000;">"Line without number: $_<span style="color: #000099; font-weight: bold;">\n</span>"</span><span style="color: #339933;">;</span> <span style="color: #009900;">}</span> <span style="color: #009900;">}</span></pre></div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/simonsilk" typeof="schema:Person" property="schema:name" datatype="">SimonSilk</span></span> <span class="field field--name-created field--type-created field--label-hidden">Mon, 11/12/2018 - 16:05</span> <div class="field field--name-category field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix field__items"> <div class="field__item"><a href="/category/category/programming" hreflang="en">Programming</a></div> </div> <section class="field field--name-comment field--type-comment field--label-above comment-wrapper"> <h2 class="title comment-form__title">Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=40&amp;2=comment&amp;3=comment" token="uf1jhokftQ9c-TrhcJdrBuejFK31TbOt8fXOfQFLDI8"></drupal-render-placeholder> </section> Mon, 12 Nov 2018 20:05:57 +0000 SimonSilk 40 at http://simonsilk.com http://simonsilk.com/blog-entry/2018-nov/processing-text-file-perl#comments Creating aliases in the Cygwin Bash terminal http://simonsilk.com/blog-entry/2018-sep/creating-aliases-cygwin-bash-terminal <span class="field field--name-title field--type-string field--label-hidden">Creating aliases in the Cygwin Bash terminal</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>If you work in a Cygwin Bash or other Linux terminal regularly, it's handy to have short hand for certain commands you execute a lot. E.g. you can navigate to the path "C:/cygwin64/lib/perl5/vendor_perl/5.26/x86_64-cygwin-threads/Text"  by typing cd followed by that entire path. But what if you need to do that 100 times a day, or just keep forgetting the full path? Wouldn't a shorthand for that be great? </p> <p>Luckily, Bash aliases allow you to do just that. Simply enter "alias name=value" in the terminal, where name is the shorthand you want to use, and value is whatever command or series of commands you want to execute with the shorthand, with double quotes if the command includes spaces. So in the case above, you would enter:</p> <p>alias Text="cd C:/cygwin64/lib/perl5/vendor_perl/5.26/x86_64-cygwin-threads/Text"</p> <p>Then you can go right to that directory by simply entering the command Text. You can also see a list of available commands by entering "alias" with no arguments. </p> <p></p><div class="geshifilter"><pre class="bash geshifilter-bash" style="font-family:monospace;">Starting <span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>bash.exe   SimonsPC <span style="color: #000000; font-weight: bold;">/</span>cygdrive<span style="color: #000000; font-weight: bold;">/</span>c<span style="color: #000000; font-weight: bold;">/</span>dev $ <span style="color: #7a0874; font-weight: bold;">alias</span>   SimonsPC <span style="color: #000000; font-weight: bold;">/</span>cygdrive<span style="color: #000000; font-weight: bold;">/</span>c<span style="color: #000000; font-weight: bold;">/</span>dev $ <span style="color: #7a0874; font-weight: bold;">alias</span> <span style="color: #007800;">Text</span>=<span style="color: #ff0000;">"cd C:/cygwin64/lib/perl5/vendor_perl/5.26/x86_64-cygwin-threads/Text"</span>   SimonsPC <span style="color: #000000; font-weight: bold;">/</span>cygdrive<span style="color: #000000; font-weight: bold;">/</span>c<span style="color: #000000; font-weight: bold;">/</span>dev $ <span style="color: #7a0874; font-weight: bold;">alias</span> <span style="color: #7a0874; font-weight: bold;">alias</span> <span style="color: #007800;">Text</span>=<span style="color: #ff0000;">'cd C:/cygwin64/lib/perl5/vendor_perl/5.26/x86_64-cygwin-threads/Text'</span>   SimonsPC <span style="color: #000000; font-weight: bold;">/</span>cygdrive<span style="color: #000000; font-weight: bold;">/</span>c<span style="color: #000000; font-weight: bold;">/</span>dev $ Text   SimonsPC <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>perl5<span style="color: #000000; font-weight: bold;">/</span>vendor_perl<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">5.26</span><span style="color: #000000; font-weight: bold;">/</span>x86_64-cygwin-threads<span style="color: #000000; font-weight: bold;">/</span>Text $</pre></div> <p> </p> <p>Great right? Well, almost. Close that Bash prompt and reopen it, and you'll find all your nice aliases have disappeared! To make them persistent, you need to add them to the end of the .bashrc file in your home folder. By default, that's "C:\cygwin64\home\&lt;user&gt;\". If you can't find the file there and you want to double check where your home directory is, do the following:</p> <p></p><div class="geshifilter"><pre class="bash geshifilter-bash" style="font-family:monospace;">SimonsPC <span style="color: #000000; font-weight: bold;">/</span>cygdrive<span style="color: #000000; font-weight: bold;">/</span>c $ <span style="color: #7a0874; font-weight: bold;">cd</span> ~   SimonsPC ~ $ cygpath <span style="color: #660033;">-w</span> <span style="color: #ff0000;">"<span style="color: #007800;">$PWD</span>"</span> C:\cygwin64\home\Simon</pre></div> <p>Bonus: To execute multiple commands with one alias, simply separate them with semi-colons. E.g. to have a single alias first move you to your Home directory then show its Windows path like the above sequence, add this:</p> <p></p><div class="geshifilter"><pre class="bash geshifilter-bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">alias</span> <span style="color: #007800;">wherehome</span>=<span style="color: #ff0000;">'cd ~;cygpath -w "$PWD";'</span></pre></div> <p>Executing that, we're moved to the Home directory, and then the Home directory's full Windows path is dumped:</p> <p></p><div class="geshifilter"><pre class="bash geshifilter-bash" style="font-family:monospace;">SimonsPC <span style="color: #000000; font-weight: bold;">/</span>cygdrive<span style="color: #000000; font-weight: bold;">/</span>c<span style="color: #000000; font-weight: bold;">/</span>dev $ wherehome C:\cygwin64\home\Simon   SimonsPC ~ $</pre></div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/simonsilk" typeof="schema:Person" property="schema:name" datatype="">SimonSilk</span></span> <span class="field field--name-created field--type-created field--label-hidden">Thu, 09/06/2018 - 22:47</span> <div class="field field--name-category field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix field__items"> <div class="field__item"><a href="/category/category/programming" hreflang="en">Programming</a></div> </div> <section class="field field--name-comment field--type-comment field--label-above comment-wrapper"> <h2 class="title comment-form__title">Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=39&amp;2=comment&amp;3=comment" token="LlETczWEdD9n00RfEBpV3q0sbSk9m84l5hhCSQ9IHxY"></drupal-render-placeholder> </section> Fri, 07 Sep 2018 01:47:46 +0000 SimonSilk 39 at http://simonsilk.com Measuring your bottom bracket axle length in situ http://simonsilk.com/blog-entry/2018-may/measuring-your-bottom-bracket-axle-length-situ <span class="field field--name-title field--type-string field--label-hidden">Measuring your bottom bracket axle length in situ</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p><img alt="Bottom Bracket Axle Length" data-entity-type="file" data-entity-uuid="e2d8e26d-c34e-4da3-95d2-9955b56d7f84" src="/sites/default/files/inline-images/BB_UN26_spindle_length.JPG" /></p> <p>Do you need to buy a replacement square taper bottom bracket for your (possibly somewhat older) bike, but you're not sure what spindle length you need? Here's a quick way to check. You just need a set of calipers and the correct allen key for removing your crank arm bolts. No need to actually remove the crank arms. </p> <p>I'm assuming you've already determined the shell width you need, e.g. British threaded 68mm or Italian threaded 70mm, and you just need to know the axle length shown below. </p> <p> </p> <p>If you've already gone through the trouble of using a crank puller to remove both cranks, then this is a no-brainer: just use your calipers to measure the axle length directly. No need to even remove the BB from the BB shell. However, if like me you have a more pedestrian toolkit of Allen keys, wrenches, and no crank puller, then try the following. </p> <p>When the cranks are installed, the end of the axle is recessed slightly below the face of the crank arm, and the crank arm bolt (usually 5mm Allen key) is screwed into it. If you remove that bolt with your basic Allen key set, you're then looking at the end of the BB axle.</p> <p>In the crude diagram below, where the crank arms are shown in purple, If you can measure the distance B between the two faces of the two crank arms, then the distances C and D from the face of each crank arm to the ends of the BB axle, you can subtract the latter two measurements to find the axle length A=B-C-D. </p> <p><img alt="Bottom Bracket Axle Length Measurement" data-entity-type="file" data-entity-uuid="3ff0350a-1346-4919-a5ec-6846140d2066" src="/sites/default/files/inline-images/BB_UN26_spindle_length_ABCD.JPG" /></p> <p> </p> <p><strong>Steps:</strong></p> <ol><li>Remove the crank arms bolts using an Allen key (probably 5mm or so). </li> <li>Place a hard flat surface like a small hard cover book against one crank arm face, then use the depth probe portion of the calipers (item 3 in the image below) through an opening in the chainrings to measure length B between the two caliper faces. </li> <li>Again use the depth probe to measure the two shorter distances C and D from each crank arm face to the end of the BB axle. </li> </ol><p> </p> <p><img alt="Vernier Caliper" data-entity-type="file" data-entity-uuid="8b7a061b-c4a3-4760-9ea0-dcb4aad6a720" src="/sites/default/files/inline-images/Vernier_caliper.svg_.png" /></p> <p><sup>From the Wikipedia <a href="https://en.wikipedia.org/wiki/Calipers">Caliper Page</a>. </sup></p> <p>I recommend for each measurement, repeat three times and average the three measurements. When I tried this on my 56cm 2010 Specialized Tricross Sport, I got the following measurements in mm:</p> <table style="border-collapse:collapse; width:192pt; border:none" width="256"><colgroup><col span="4" style="width:48pt" width="64" /></colgroup><tbody><tr height="20" style="height:15.0pt"><td class="xl63" height="20" style="border:0.5pt solid windowtext; height:15.0pt; width:48pt; text-align:center; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap" width="64"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">Meas.</span></span></span></span></span></span></td> <td class="xl63" style="border:0.5pt solid windowtext; border-left:none; width:48pt; text-align:center; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap" width="64"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">B</span></span></span></span></span></span></td> <td class="xl63" style="border:0.5pt solid windowtext; border-left:none; width:48pt; text-align:center; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap" width="64"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">C</span></span></span></span></span></span></td> <td class="xl63" style="border:0.5pt solid windowtext; border-left:none; width:48pt; text-align:center; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap" width="64"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">D</span></span></span></span></span></span></td> </tr><tr height="20" style="height:15.0pt"><td class="xl63" height="20" style="border:0.5pt solid windowtext; height:15.0pt; border-top:none; text-align:center; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">1</span></span></span></span></span></span></td> <td align="right" class="xl64" style="border:0.5pt solid windowtext; border-top:none; border-left:none; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">139.20</span></span></span></span></span></span></td> <td align="right" class="xl64" style="border:0.5pt solid windowtext; border-top:none; border-left:none; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">11.23</span></span></span></span></span></span></td> <td align="right" class="xl64" style="border:0.5pt solid windowtext; border-top:none; border-left:none; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">12.14</span></span></span></span></span></span></td> </tr><tr height="20" style="height:15.0pt"><td class="xl63" height="20" style="border:0.5pt solid windowtext; height:15.0pt; border-top:none; text-align:center; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">2</span></span></span></span></span></span></td> <td align="right" class="xl64" style="border:0.5pt solid windowtext; border-top:none; border-left:none; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">140.61</span></span></span></span></span></span></td> <td align="right" class="xl64" style="border:0.5pt solid windowtext; border-top:none; border-left:none; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">11.10</span></span></span></span></span></span></td> <td align="right" class="xl64" style="border:0.5pt solid windowtext; border-top:none; border-left:none; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">11.83</span></span></span></span></span></span></td> </tr><tr height="20" style="height:15.0pt"><td class="xl63" height="20" style="border:0.5pt solid windowtext; height:15.0pt; border-top:none; text-align:center; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">3</span></span></span></span></span></span></td> <td align="right" class="xl64" style="border:0.5pt solid windowtext; border-top:none; border-left:none; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">139.97</span></span></span></span></span></span></td> <td align="right" class="xl64" style="border:0.5pt solid windowtext; border-top:none; border-left:none; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">11.05</span></span></span></span></span></span></td> <td align="right" class="xl64" style="border:0.5pt solid windowtext; border-top:none; border-left:none; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">11.81</span></span></span></span></span></span></td> </tr><tr height="20" style="height:15.0pt"><td class="xl63" height="20" style="border:0.5pt solid windowtext; height:15.0pt; border-top:none; text-align:center; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">Avg</span></span></span></span></span></span></td> <td align="right" class="xl64" style="border:0.5pt solid windowtext; border-top:none; border-left:none; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">139.93</span></span></span></span></span></span></td> <td align="right" class="xl64" style="border:0.5pt solid windowtext; border-top:none; border-left:none; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">11.13</span></span></span></span></span></span></td> <td align="right" class="xl64" style="border:0.5pt solid windowtext; border-top:none; border-left:none; padding-top:1px; padding-right:1px; padding-left:1px; vertical-align:bottom; white-space:nowrap"><span style="font-size:11pt"><span style="color:black"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"><span style="font-family:Calibri,sans-serif">11.93</span></span></span></span></span></span></td> </tr></tbody></table><p>This gives a final BB axle length measurement of A = 139.93-11.13-11.93 = 116.87mm.</p> <p>Looking at the options available for the Shimano BB-UN55 Square taper BB in shell widths 68mm, I see 107, 113, 115, 118, and 127mm. Of those, the closest to what I measured is 118mm. I later properly removed my cranks at a bike co-op and found that my BB is indeed a 68mm x 118mm. </p> <p>I hope this helps you determine your BB axle length if you do not have a crank puller at hand. If you really want to be sure ahead of buying a new BB, see if your city has a bike co-op where you can swing by and use a crank puller to remove your cranks, allowing direct measurement of the axle length with calipers. </p> <p>Thanks for reading! </p> <p> </p> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/simonsilk" typeof="schema:Person" property="schema:name" datatype="">SimonSilk</span></span> <span class="field field--name-created field--type-created field--label-hidden">Fri, 05/04/2018 - 21:09</span> <div class="field field--name-tags field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix field__items"> <div class="field__item"><a href="/taxonomy/term/33" hreflang="en">bicycles</a></div> </div> <section class="field field--name-comment field--type-comment field--label-above comment-wrapper"> <h2 class="title comment-form__title">Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=37&amp;2=comment&amp;3=comment" token="gvF5wqRkvRYszrMOWAxHDjMIL25UoMLzXWdz7viFYPw"></drupal-render-placeholder> </section> Sat, 05 May 2018 00:09:55 +0000 SimonSilk 37 at http://simonsilk.com Hiking to Castelo dos Mouros http://simonsilk.com/blog-entry/2018-apr/hiking-castelo-dos-mouros <span class="field field--name-title field--type-string field--label-hidden">Hiking to Castelo dos Mouros</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p><img alt="Castelo dos Mouros" data-entity-type="file" data-entity-uuid="d55eed3e-8b48-4ddc-8350-f83400db41ea" src="/sites/default/files/inline-images/Castelo_dos_Mouros.jpg" /></p> <p>Castelo dos Mouros (Castle of the Moors) is a scenic 8th century Moorish castle overlooking Sintra, just outside Lisbon, Portugal. It was my second favorite part of my visit to Sintra after the Quinta de Regeleira, mostly because of the great hike up and down. </p> <p>There are two routes to the castle: the "front way" via the Caminho De Santa Maria, and the "back way" via Rampa Da Pena/ Caminho Do Vale Dos Anjos. I hiked up the back way and down the front way. The back way's a tiny bit tricky to find but well worth it as it is less trafficked. To get to the starting point, go to the Quinta de Regaleira, then continue uphill past the main entrance, around to the last (locked) side entrance to the grounds of the Quinta. Right next to it is a small unkempt gravel trail marked most prominently as "Rampa da Pena", and with a smaller sign on the side for "Azhinga Do Vale Dos Anjos":</p> <p><img alt="Rampa da Pena" data-entity-type="file" data-entity-uuid="ea97b3e7-7dab-4d81-9bac-2396f501c9c6" src="/sites/default/files/inline-images/Rampa_da_Pena_0.jpg" /></p> <p>The exact start point is right <a href="https://www.google.ca/maps/place/Rampa+Da+Pena/@38.7960375,-9.3977999,17z/data=!4m13!1m7!3m6!1s0xd1edac1a7510ee9:0x13585cc0b00f573c!2sSintra,+Portugal!3b1!8m2!3d38.8028687!4d-9.3816589!3m4!1s0x0:0x89569d40a2a79294!8m2!3d38.795862!4d-9.398559">here</a> on Google Maps:</p> <p><img alt="Rampa da Pena on Google Maps" data-entity-type="file" data-entity-uuid="80d477e8-e2fb-4bd5-9a43-189a301a6424" src="/sites/default/files/inline-images/Screen_Shot_04-01-18_at_05.27_PM.JPG" /></p> <p>From there, you're looking at about a 3.5km hike before you hit the grounds of the castle proper.</p> <p>Around the 1.3km mark (10-20 minutes in), the trail pops out on the road. At that point, you can either walk along the road for a couple of switchbacks before picking up the trail again, or keep your eyes peeled for a small unmarked set of stone steps about 40m up the road on the opposite side. Scrabble up those onto a rough path, marked by the dotted line below, that patches you back onto the main trail:</p> <p><img alt="Caminho Do Vale Dos Anjos shortcut around switchbacks" data-entity-type="file" data-entity-uuid="e1613f22-3097-4c72-b5f4-57d175045d00" src="/sites/default/files/inline-images/Caminho_Do_Vale_Dos_Anjos_shortcut.jpg" /></p> <p>When you're done at Castelo dos Mouros, you can come back down the same way, or use the Caminho De Santa Maria whichs pops you out, if you can believe it, by the Igreja de Santa Maria. That trail is maintained cobblestone and more heavily trafficked:</p> <p><img alt="Camiho de Santa Maria" data-entity-type="file" data-entity-uuid="811b88ea-4b4a-4d40-8d77-0cdafb3628db" src="/sites/default/files/inline-images/Camiho_de_Santa_Maria.jpg" /></p> <p>One tip I have for visiting the castle is to go there later in the day. During the day, there are tour buses that drive tourists up there, let them explore for a couple hours, then bring them back down. Those bus packages seem to wind down around 5pm, but the castle <a href="http://www.sintra-portugal.com/Attractions/Castle-Moors-Sintra.html">is open until 8pm in the summer</a>, so if you get up there after 5, it is a lot less busy. When I went, I got there around 5:30, and there were only about 5 other people on the castle grounds with me. </p> <p>Another thing I would love to do if I had my time back is try riding up the Rampa Da Pena/ Caminho Do Vale Dos Anjos trail on a gravel or cyclocross bike. If anyone has tried this, please let me know. </p> <p>Happy hiking! </p> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/simonsilk" typeof="schema:Person" property="schema:name" datatype="">SimonSilk</span></span> <span class="field field--name-created field--type-created field--label-hidden">Tue, 03/13/2018 - 21:39</span> <div class="field field--name-tags field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix field__items"> <div class="field__item"><a href="/taxonomy/term/31" hreflang="en">Portugal</a></div> <div class="field__item"><a href="/taxonomy/term/32" hreflang="en">Travel</a></div> </div> <section class="field field--name-comment field--type-comment field--label-above comment-wrapper"> <h2 class="title comment-form__title">Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=36&amp;2=comment&amp;3=comment" token="5eDklJfT4NxvvLxFLpKSLCtmXzwwAdpl5L5jpEDPysM"></drupal-render-placeholder> </section> Wed, 14 Mar 2018 00:39:05 +0000 SimonSilk 36 at http://simonsilk.com Fast High Dynamic Range Image Deghosting for Arbitrary Scene Motion http://simonsilk.com/content/fast-hdr-deghosting-arbitrary-motion <span property="schema:name" class="field field--name-title field--type-string field--label-hidden">Fast High Dynamic Range Image Deghosting for Arbitrary Scene Motion</span> <span rel="schema:author" class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/simonsilk" typeof="schema:Person" property="schema:name" datatype="">SimonSilk</span></span> <span property="schema:dateCreated" content="2012-03-15T01:08:20+00:00" class="field field--name-created field--type-created field--label-hidden">Wed, 03/14/2012 - 22:08</span> <drupal-render-placeholder callback="flag.link_builder:build" arguments="0=node&amp;1=28&amp;2=bookmark" token="_l3LYzF4tNfJPgnJMyZ1ccaHt3jXUo6PkjGgwqler5U"></drupal-render-placeholder> <div property="schema:text" class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p class="rtecenter"><a href="http://web.cs.dal.ca/~sbrooks/gi2012/" target="_blank">Graphics Interface 2012</a></p> <p class="rtecenter"> </p> <p class="rtecenter"><a href="http://www.simonsilk.com">Simon Silk</a>                                    <a href="http://www.site.uottawa.ca/%7Ejlang/index.html" target="_blank">Jochen Lang</a></p> <p class="rtecenter"> </p> <p class="rtecenter">School of Electrical Engineering and Computer Science</p> <p class="rtecenter">University of Ottawa</p> <p> </p> <h2>Abstract</h2> <p><em>High Dynamic Range (HDR) images of real world scenes often suffer from ghosting artifacts caused by motion in the scene. Existing solutions to this problem typically either only address specific types of ghosting, or are very computationally expensive.</em></p> <p><em>We address ghosting by performing change detection on exposure-normalized images, then reducing the contribution of moving objects to the final composite on a frame-by-frame basis. Change detection is computationally advantagous and it can be applied to images exhibiting varied ghosting artifacts. We demonstrate our method both for Low Dynamic Range (LDR) and HDR images. Additional constraints based on a priori knowledge of the changing exposures apply to HDR images. We increase the stability of our approach by using recent superpixel segmentation techniques to enhance the change detection. Our solution includes a novel approach for areas that see motion throughout the capture, e.g., foliage blowing in the wind.</em></p> <!--break--><p><em>We demonstrate the success of our approach on challenging ghosting scenarios, and that our results are comparable to existing state-of- the-art methods, while providing computational savings over these methods.</em></p> <hr /><p> </p> <p>Welcome to the supplementary material page for our paper <strong>Fast High Dynamic Range Image Deghosting for Abitrary Scene Motion</strong>, which will be presented at Graphics Interface 2012 in Toronto, Canada.</p> <h2>Data sets</h2> <p>The data sets used in our paper are posted below. Each is in a separate zip file. The files are in ppm format (<a href="http://www.irfanview.com/" target="_blank">IrfanView</a> is a good free viewer) and includes the exposure data in the form of a hdrgen file of the same format used by <a href="http://pfstools.sourceforge.net/pfscalibration.html" target="_blank">pfscalibrate</a> (see <a href="http://www.mpi-inf.mpg.de/resources/hdr/calibration/pfs.html" target="_blank">here</a> for a description of that file format and how to use it in pfscalibrate).</p> <p><a href="/sites/default/files/2018-04/Marion.rar">Marion Lot data set</a></p> <p> </p> <h2>Code</h2> <p>We have released our MATLAB code for this paper. To try it out, grab a copy, and a data set from above. It uses <a href="http://ivrg.epfl.ch/research/superpixels" target="_blank">SLIC superpixels</a>, by Achanta et. al., via a MEX wrapper; for this, we currently include only precompiled MEX binaries for 32-bit and 64-bit Windows, but we hope to include source code for that component soon.</p> <p><a href="http://simonsilk.com/sites/default/files/2018-03/fast_HDR_deghosting.rar">Source Code</a></p> <p> </p> <h2>Paper</h2> <p>S. Silk and J. Lang, “Fast High Dynamic Range Image Deghosting for Abitrary Scene Motion,” in <em>Proc. Graphics Interface</em>, 2012.</p> <p> </p> <p>BibTeX:</p> <p>@INPROCEEDINGS{silk2012fast,<br />   author = {Silk, Simon and Lang, Jochen},<br />   title = {Fast high dynamic range image deghosting for abitrary scene motion},<br />   booktitle = {Proc. Graphics Interface},<br />   year = {2012},<br /> }</p> </div> Thu, 15 Mar 2012 01:08:20 +0000 SimonSilk 28 at http://simonsilk.com LaTeX: List of Notations (Nomenclature) http://simonsilk.com/content/simonsilk/2011-jun/latex-list-notations-nomenclature <span class="field field--name-title field--type-string field--label-hidden">LaTeX: List of Notations (Nomenclature)</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p><strong>Update for MikTeX 2.9 below.</strong></p> <p> </p> <p>I've been working on my thesis for a couple of months now, and frequently I have to look up ways to tweak certain Latex components, so I'm going to start posting about these tweaks, even if it's just to link to another page about how to do something. If I end up having a good collection at the end of my thesis, then I can write a final post aggregating them in a logical order so they can serve as a guide to formatting a thesis in Latex.</p> <p> </p> <p>I'm using <a href="http://www.texniccenter.org/" target="_blank">TeXnic Center</a> (TXC) 2 Alpha 3 to edit and MikTeX to build. I originally installed both using <a href="http://www.tug.org/protext/" target="_blank">ProTeXt</a> which packages TXC1, MikTeX, Ghostscript, and Ghostgum. I later installed TXC2 which provides a much-needed overhaul to the interface so that toolbars don't shift all over the place whenever you resize the window.</p> <p> </p> <p>Today, I decided to add a List of Notations (aka list of Symbols) to my thesis. This is handy in a scientific thesis to let readers quickly refer to the list in case there's a symbol they're unfamiliar with. It's also nice if you can do your Related Work review (Lit Review) using one common set of notation, which will allow readers to more easily understand the relationship between various other papers you're reviewing in case they don't share notation.</p> <p> </p> <p>The list of notations can be generated using <a href="http://www.ctan.org/tex-archive/macros/latex/contrib/glossaries" target="_blank">glossaries</a>, or even manually, but it's best done using the package <a href="http://ctan.org/tex-archive/macros/latex/contrib/nomencl/" target="_blank"><em>nomencl</em></a>, which was designed for this purpose. If you're using MikTex, then you should have this already.</p> <p> </p> <p>Anyway, as outlined <a href="http://ytyoun.wordpress.com/2010/04/18/latex-list-of-notations-using-nomencl-sty/" target="_blank">here</a>, adding a list of notations can be done in 4 simple steps:</p> <p> </p> <p><em><strong>1. Add the following code to your preamble:</strong></em></p> <p> </p> <p></p><div class="geshifilter"><pre class="latex geshifilter-latex" style="font-family:monospace;"><span style="color: #E02020; ">\</span><a href="http://www.golatex.de/wiki/%5Cusepackage"><span style="color: #800000;">usepackage</span></a><span style="color: #E02020; ">[</span><span style="color: #C08020; font-weight: normal;">refpage</span><span style="color: #E02020; ">]{</span><span style="color: #2020C0; font-weight: normal;">nomencl<span style="color: #E02020; ">}</span> <span style="color: #E02020; ">\</span><a href="http://www.golatex.de/wiki/%5Crenewcommand"><span style="color: #800000;">renewcommand</span></a><span style="color: #E02020; ">{</span><span style="color: #800000; font-weight: normal;">\nomname</span><span style="color: #E02020; ">}{</span>List of Notations<span style="color: #E02020; ">}</span> <span style="color: #E02020; ">\</span><a href="http://www.golatex.de/wiki/%5Crenewcommand"><span style="color: #800000;">renewcommand</span></a>*<span style="color: #E02020; ">{</span><span style="color: #800000; font-weight: normal;">\pagedeclaration</span><span style="color: #E02020; ">}[</span><span style="color: #C08020; font-weight: normal;">1</span><span style="color: #E02020; ">]{</span><span style="color: #800000; font-weight: normal;">\unskip</span><span style="color: #800000; font-weight: normal;">\dotfill</span><span style="color: #800000; font-weight: normal;">\hyperpage</span><span style="color: #E02020; ">{</span>#1<span style="color: #E02020; ">}}</span> <span style="color: #800000; font-weight: normal;">\makenomenclature</span>     <span style="color: #E02020; ">\</span><a href="http://www.golatex.de/wiki/%5Cusepackage"><span style="color: #800000;">usepackage</span></a>{makeidx</span><span style="color: #E02020; ">}</span> <span style="color: #E02020; ">\</span><a href="http://www.golatex.de/wiki/%5Cmakeindex"><span style="color: #800000;">makeindex</span></a></pre></div> <p> </p> <!--break--><p>The first line invokes the nomenclature package, and the option refpage means that the list will include, for each symbol in the list,  the page number on which you added it with the <em>\nomenclature</em> command. Leave it out to remove page numbers. The second line is the title at the top of the list of notations. The third line changes the page numbers in the list so they are right-justified with a line of dots connecting them back to the description of the symbol. By default, they follow the description after a comma and the word "page." The last line tells Latex you're using nomenclature so it will generate and look for the associated intermediate files during successive runs.</p> <p> </p> <p>The last two lines are likely somewhere in your preamble already, but if not add them because nomencl depends on makeindex.</p> <p> </p> <p><em><strong>2. Add the following where you want the nomenclature to appear.</strong></em> For example, you might place it right after <em>\listoffigures. </em></p> <p> </p> <p></p><div class="geshifilter"><pre class="latex geshifilter-latex" style="font-family:monospace;"><span style="color: #800000; font-weight: normal;">\printnomenclature</span></pre></div> <p> </p> <p><em><strong>3. Use the following command when you want to add a new symbol.</strong></em></p> <p> </p> <p></p><div class="geshifilter"><pre class="latex geshifilter-latex" style="font-family:monospace;"><span style="color: #800000; font-weight: normal;">\nomenclature</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;"><span style="color: #8020E0; font-weight: normal;">$symbol$</span>}{Description</span><span style="color: #E02020; ">}</span></pre></div> <p> </p> <p>For example, you might say:</p> <p> </p> <p></p><div class="geshifilter"><pre class="latex geshifilter-latex" style="font-family:monospace;"><span style="color: #800000; font-weight: normal;">\nomenclature</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;"><span style="color: #8020E0; font-weight: normal;">$<span style="color: #800000; font-weight: normal;">\alpha</span>$</span>}{Angular Velocities</span><span style="color: #E02020; ">}</span></pre></div> <p> </p> <p><em><strong>4. Run latex (or pdflatex, xelatex, etc.), then makeidx twice, then latex again</strong></em>, just like when you want to generate an index. Check your results. If you're using TeXnic center, this won't work automatically just using successive builds. See below.</p> <p> </p> <p>For a complete code example, please see <a href="http://ytyoun.wordpress.com/2010/04/18/latex-list-of-notations-using-nomencl-sty/" target="_blank">this post</a>.</p> <p> </p> <h3>Using nomencl in TeXnic center.</h3> <p> </p> <p>As oultined <a href="http://eldemet.wordpress.com/2009/08/06/using-nomenclatures-in-texniccenter/" target="_blank">here</a>, you need to add makeindex with nomencl arguments as a post-processor option. To do so, go <em>Build &gt; Define Output Profiles</em>, and choose your desired output profile, e.g. <em>LaTeX =&gt; PDF</em>. Go to the postprocessor tab and add a new postprocessor using the button that looks like a New Folder in TXC2. Give it a name, then add the path to the makeindex executable (<em>C:\Program Files (x86)\MiKTeX 2.8\miktex\bin\makeindex.exe</em> in my case). Then add <em>-s  nomencl.ist "%bm.nlo" -o "%bm.nls"</em>  to the arguments list. Now three builds in TXC should produce an updated nomenclature with page references.</p> <p> </p> <p><span id="cke_bm_345S" style="display: none;"> </span><span id="cke_bm_346S" style="display: none;"> </span></p> <h3>Optional Tweaks<span id="cke_bm_346E" style="display: none;"> </span><span id="cke_bm_345E" style="display: none;"> </span></h3> <p> </p> <p><em><strong>Column spacing in the list of notations</strong></em></p> <p> </p> <p>If some of your symbol entries are too long, they will push their description to the right in your table, but others will stay where they are, which is ugly. You can fix this with the label width option, inserted in the preamble just before <em>\makenomenclature</em>:</p> <p> </p> <p></p><div class="geshifilter"><pre class="latex geshifilter-latex" style="font-family:monospace;"><span style="color: #800000; font-weight: normal;">\nomlabelwidth</span>=25mm</pre></div> <p> </p> <p>The default is 0.5cm.</p> <p> </p> <p><em><strong>Where to inset \nomenclature commands. </strong></em></p> <p> </p> <p>If you don't want page numbers, and don't really care where in your document this command is given, you can just place all the <em>\nomenclature </em>commands in one tex file, say <em>symbols.tex</em>, then insert this anywhere in your document body with <em>\input{symbols}</em>. This can be handy if you've already written your lit review using multiple authors' notations and you now want to bring them under one common notation set; just do this first to make your list of notations, then print yourself a copy and go through your lit review updating notation where necessary.</p> <p> </p> <p><em><strong>Update for MikTeX 2.9</strong></em></p> <p> </p> <p>As per <a href="http://comments.gmane.org/gmane.comp.tex.miktex/10259" target="_blank">this post</a>, with newer versions of Makeindex, <em>makeindex.exe</em> needs to be passed a relative rather than absolute pathname. This can be achieved by replacing <em>%bm</em> with<em> %tm </em>in the output profiles of TeXnice Center. Don't forget to change it in the post-processor tab as well so that Nomenclature will work.</p> <p> </p> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/simonsilk" typeof="schema:Person" property="schema:name" datatype="">SimonSilk</span></span> <span class="field field--name-created field--type-created field--label-hidden">Mon, 06/27/2011 - 18:02</span> <div class="field field--name-tags field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix field__items"> <div class="field__item"><a href="/category/tags/latex" hreflang="en">LaTeX</a></div> </div> <section class="field field--name-comment field--type-comment field--label-above comment-wrapper"> <h2 class="title">Comments</h2> <a id="comment-15"></a> <article role="article" data-comment-user-id="0" about="/comment/15" typeof="schema:Comment" class="comment js-comment by-anonymous clearfix"> <span class="hidden new-indicator" data-comment-timestamp="1341457772"></span> <header> <article typeof="schema:Person" about="/user/0" class="profile"> <drupal-render-placeholder callback="flag.link_builder:build" arguments="0=user&amp;1=0&amp;2=following" token="dV8BLmhD339z_wMjaUSDxONyVEf9d6Tb-DESjU5tHGA"></drupal-render-placeholder></article> </header> <div class="comment__content-container"> <nav class="comment__links"><drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=15&amp;1=default&amp;2=en&amp;3=" token="rNqCNcQQOXfzbkOZt-lpzNIGd8-5jMcJXc7motnrTtc"></drupal-render-placeholder></nav> <div class="comment__meta"> <span>Submitted by <span rel="schema:author"><span lang="" typeof="schema:Person" property="schema:name" datatype="">Anonymous (not verified)</span></span> Thu, 07/05/2012 - 00:09 <span property="schema:dateCreated" content="2012-07-05T03:09:32+00:00" class="rdf-meta hidden"></span> </span> </div> <h3 property="schema:name" datatype="" class="title"><a href="/comment/15#comment-15" class="permalink" rel="bookmark" hreflang="en">Thanks</a></h3> <div class="comment__content"> <div property="schema:text" class="clearfix text-formatted field field--name-comment-body field--type-text-long field--label-hidden field__item">Hi, I got exactly I was looking for. Thanks a lot.</div> </div> </div> </article> <a id="comment-18"></a> <article role="article" data-comment-user-id="0" about="/comment/18" typeof="schema:Comment" class="comment js-comment by-anonymous clearfix"> <span class="hidden new-indicator" data-comment-timestamp="1355759597"></span> <header> <article typeof="schema:Person" about="/user/0" class="profile"> <drupal-render-placeholder callback="flag.link_builder:build" arguments="0=user&amp;1=0&amp;2=following" token="dV8BLmhD339z_wMjaUSDxONyVEf9d6Tb-DESjU5tHGA"></drupal-render-placeholder></article> </header> <div class="comment__content-container"> <nav class="comment__links"><drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=18&amp;1=default&amp;2=en&amp;3=" token="jVhirhDd91eC6XV9WsQl4PLehFgKsOgX9j8i4FgvScs"></drupal-render-placeholder></nav> <div class="comment__meta"> <span>Submitted by <span rel="schema:author"><span lang="" typeof="schema:Person" property="schema:name" datatype="">Anonymous (not verified)</span></span> Mon, 12/17/2012 - 11:53 <span property="schema:dateCreated" content="2012-12-17T15:53:17+00:00" class="rdf-meta hidden"></span> </span> </div> <h3 property="schema:name" datatype="" class="title"><a href="/comment/18#comment-18" class="permalink" rel="bookmark" hreflang="en">Hi, I&#039;m using nomenclature</a></h3> <div class="comment__content"> <div property="schema:text" class="clearfix text-formatted field field--name-comment-body field--type-text-long field--label-hidden field__item">Hi, I'm using nomenclature after \listoftables and \listoffigures, and before the beginning of the first chapter. My problem is that every of the firsts commands create a second blank page with only the header and page number, however nomenclature don't, and there is a second blank page after nomenclature with the header of listoffigures. It seems like latex don't know listoffigures end before nomenclature or something like that. By the way, listoffigures, of tables, etc. are not in the index (makeindex), and nomenclature does. Please help!!</div> </div> </div> </article> <a id="comment-32"></a> <article role="article" data-comment-user-id="0" about="/comment/32" typeof="schema:Comment" class="comment js-comment by-anonymous clearfix"> <span class="hidden new-indicator" data-comment-timestamp="1358529461"></span> <header> <article typeof="schema:Person" about="/user/0" class="profile"> <drupal-render-placeholder callback="flag.link_builder:build" arguments="0=user&amp;1=0&amp;2=following" token="dV8BLmhD339z_wMjaUSDxONyVEf9d6Tb-DESjU5tHGA"></drupal-render-placeholder></article> </header> <div class="comment__content-container"> <nav class="comment__links"><drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=32&amp;1=default&amp;2=en&amp;3=" token="jq4Ec-y1qsP57EP-n5He1zEXIj34lMlEXe7GGeXB2RI"></drupal-render-placeholder></nav> <div class="comment__meta"> <span>Submitted by <span rel="schema:author"><span lang="" typeof="schema:Person" property="schema:name" datatype="">Anonymous (not verified)</span></span> Fri, 01/18/2013 - 13:17 <span property="schema:dateCreated" content="2013-01-18T17:17:41+00:00" class="rdf-meta hidden"></span> </span> </div> <h3 property="schema:name" datatype="" class="title"><a href="/comment/32#comment-32" class="permalink" rel="bookmark" hreflang="en">Thank you very very much</a></h3> <div class="comment__content"> <div property="schema:text" class="clearfix text-formatted field field--name-comment-body field--type-text-long field--label-hidden field__item">Thank you and thank god for this article. Much better than what the guy Bernd Schandl wrote. As opposed to that "main" article of Bernd, this actually works!!!! Using Texmaker, all I did is: 1) Open the main "name.tex" file 2) Put: " \usepackage[refpage]{nomencl} \renewcommand{\nomname}{List of Notations} \renewcommand*{\pagedeclaration}[1]{\unskip\dotfill\hyperpage{#1}} \makenomenclature \usepackage{makeidx} \makeindex " between "\documentclass[11pt]{report}" and "\begin{document}" 3) Compile with "Quick Build" 4) Type "makeindex name.nlo -s nomencl.ist -o name.nls" into the black command window. In Texmaker its under "Tools" and "Open Terminal". 5) Then I compiled by switching from mode "Quick Build" to "MakeIndex" and I compile. 6) Go back to "Quick Build" and compile. That's it then I was happy to see my list of notations.</div> </div> </div> </article> <a id="comment-33"></a> <article role="article" data-comment-user-id="0" about="/comment/33" typeof="schema:Comment" class="comment js-comment by-anonymous clearfix"> <span class="hidden new-indicator" data-comment-timestamp="1359095753"></span> <header> <article typeof="schema:Person" about="/user/0" class="profile"> <drupal-render-placeholder callback="flag.link_builder:build" arguments="0=user&amp;1=0&amp;2=following" token="dV8BLmhD339z_wMjaUSDxONyVEf9d6Tb-DESjU5tHGA"></drupal-render-placeholder></article> </header> <div class="comment__content-container"> <nav class="comment__links"><drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=33&amp;1=default&amp;2=en&amp;3=" token="mK-J0A8X34ALX2iIJHbM3TrtGCfKFG4ODtJyKpXPO3Q"></drupal-render-placeholder></nav> <div class="comment__meta"> <span>Submitted by <span rel="schema:author"><span lang="" typeof="schema:Person" property="schema:name" datatype="">Anonymous (not verified)</span></span> Fri, 01/25/2013 - 02:35 <span property="schema:dateCreated" content="2013-01-25T06:35:53+00:00" class="rdf-meta hidden"></span> </span> </div> <h3 property="schema:name" datatype="" class="title"><a href="/comment/33#comment-33" class="permalink" rel="bookmark" hreflang="en">Thank you</a></h3> <div class="comment__content"> <div property="schema:text" class="clearfix text-formatted field field--name-comment-body field--type-text-long field--label-hidden field__item">Great little tutorial. Saved me a lot of trouble. Thank you.</div> </div> </div> </article> <a id="comment-36"></a> <article role="article" data-comment-user-id="0" about="/comment/36" typeof="schema:Comment" class="comment js-comment by-anonymous clearfix"> <span class="hidden new-indicator" data-comment-timestamp="1362500595"></span> <header> <article typeof="schema:Person" about="/user/0" class="profile"> <drupal-render-placeholder callback="flag.link_builder:build" arguments="0=user&amp;1=0&amp;2=following" token="dV8BLmhD339z_wMjaUSDxONyVEf9d6Tb-DESjU5tHGA"></drupal-render-placeholder></article> </header> <div class="comment__content-container"> <nav class="comment__links"><drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=36&amp;1=default&amp;2=en&amp;3=" token="p5cbrQ-JXGqnV8y40KOWbSfElb2H2M3H6m4sKApSohQ"></drupal-render-placeholder></nav> <div class="comment__meta"> <span>Submitted by <span rel="schema:author"><span lang="" typeof="schema:Person" property="schema:name" datatype="">Anonymous (not verified)</span></span> Tue, 03/05/2013 - 12:23 <span property="schema:dateCreated" content="2013-03-05T16:23:15+00:00" class="rdf-meta hidden"></span> </span> </div> <h3 property="schema:name" datatype="" class="title"><a href="/comment/36#comment-36" class="permalink" rel="bookmark" hreflang="en">Great post, really helpful!</a></h3> <div class="comment__content"> <div property="schema:text" class="clearfix text-formatted field field--name-comment-body field--type-text-long field--label-hidden field__item">Great post, really helpful!</div> </div> </div> </article> <a id="comment-40"></a> <article role="article" data-comment-user-id="0" about="/comment/40" typeof="schema:Comment" class="comment js-comment by-anonymous clearfix"> <span class="hidden new-indicator" data-comment-timestamp="1365665263"></span> <header> <article typeof="schema:Person" about="/user/0" class="profile"> <drupal-render-placeholder callback="flag.link_builder:build" arguments="0=user&amp;1=0&amp;2=following" token="dV8BLmhD339z_wMjaUSDxONyVEf9d6Tb-DESjU5tHGA"></drupal-render-placeholder></article> </header> <div class="comment__content-container"> <nav class="comment__links"><drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=40&amp;1=default&amp;2=en&amp;3=" token="8RxD22SSj5vnfxJTLnnbwsswMZnJXz7H4QvoCZiQGPQ"></drupal-render-placeholder></nav> <div class="comment__meta"> <span>Submitted by <span rel="schema:author"><span lang="" typeof="schema:Person" property="schema:name" datatype="">Anonymous (not verified)</span></span> Thu, 04/11/2013 - 04:27 <span property="schema:dateCreated" content="2013-04-11T07:27:43+00:00" class="rdf-meta hidden"></span> </span> </div> <h3 property="schema:name" datatype="" class="title"><a href="/comment/40#comment-40" class="permalink" rel="bookmark" hreflang="en">Thanks!</a></h3> <div class="comment__content"> <div property="schema:text" class="clearfix text-formatted field field--name-comment-body field--type-text-long field--label-hidden field__item">Thanks for great tips, Simon! You probably saved me from several hours' work. :)</div> </div> </div> </article> <a id="comment-42"></a> <article role="article" data-comment-user-id="0" about="/comment/42" typeof="schema:Comment" class="comment js-comment by-anonymous clearfix"> <span class="hidden new-indicator" data-comment-timestamp="1377566693"></span> <header> <article typeof="schema:Person" about="/user/0" class="profile"> <drupal-render-placeholder callback="flag.link_builder:build" arguments="0=user&amp;1=0&amp;2=following" token="dV8BLmhD339z_wMjaUSDxONyVEf9d6Tb-DESjU5tHGA"></drupal-render-placeholder></article> </header> <div class="comment__content-container"> <nav class="comment__links"><drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=42&amp;1=default&amp;2=en&amp;3=" token="jTyXG9yPp5HG-5eFR3y5lHxuBvcV4a0q5S4t0pXGl_g"></drupal-render-placeholder></nav> <div class="comment__meta"> <span>Submitted by <span rel="schema:author"><span lang="" typeof="schema:Person" property="schema:name" datatype="">Anonymous (not verified)</span></span> Mon, 08/26/2013 - 22:24 <span property="schema:dateCreated" content="2013-08-27T01:24:53+00:00" class="rdf-meta hidden"></span> </span> </div> <h3 property="schema:name" datatype="" class="title"><a href="/comment/42#comment-42" class="permalink" rel="bookmark" hreflang="en">Works perfectly!</a></h3> <div class="comment__content"> <div property="schema:text" class="clearfix text-formatted field field--name-comment-body field--type-text-long field--label-hidden field__item">Did the steps using Miktex 2.9 and Texnic Center 2.0 Beta and everything worked like a charm following the provided steps!!</div> </div> </div> </article> <h2 class="title comment-form__title">Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=27&amp;2=comment&amp;3=comment" token="TA0hR5mKqqgyHVFJ9N2hid4Y-krX49ZXWc4IWg3H7iI"></drupal-render-placeholder> </section> Mon, 27 Jun 2011 21:02:49 +0000 SimonSilk 27 at http://simonsilk.com Pixel Format Conversions http://simonsilk.com/content/simonsilk/2011-mar/pixel-format-conversions <span class="field field--name-title field--type-string field--label-hidden">Pixel Format Conversions</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>I recently found myself having to do a few interesting conversions in C++ to pass images between different formats and/ or libraries, including OpenCV, MATLAB, and some unusual custom formats. I'm going to post some code snippets here that do some of these conversions as I suspect they may be useful for others.</p> <p> </p> <p>Keep in mind that, generally, image data is always stored in one long array, and you have a pointer to the beginning of that array. So, the question is, as you increment your way through the array contents, in what order are you traversing the image's data? E.g. are the first three elements the RGB values of the first pixel in the top left corner of the image? Or are they the R components of the first three pixels moving right along the top row of the image? Or something else entirely?</p> <p> </p> <!--break--><p>As it turns out, this depends on what library/ API/ SDK/ whatever you are using to handle images. You may often want to use multiple image types in the same project so that you can leverage the capabilities of different libraries or programs, for example using ImageMagick to load some obscure image format, then transferring the loaded image data into an OpenCV Mat structure so you can use OpenCV's routines on it. As a results, being able to quickly convert between these different pixel formats is very handy.</p> <p> </p> <p>A few handy defiintions will make the conversions I'm describing a litte more clear.</p> <p> </p> <p><strong><a href="http://en.wikipedia.org/wiki/Row-major_order" target="_blank">Row-major order</a></strong> means that as we increment through the array, we first move along the top-most row of the matrix (image), then along columns, i.e. when we get to the last entry on the first row and increment one more place, we are at the first pixel of the next horizontal row. This is the most common way to handle matrices in C and C++. <strong>Column-major</strong> should now be self-explanatory; as we increment through an array, we are first moving down the left-most column of the matrix, then along rows.</p> <p> </p> <p><strong>Interleaved </strong>color channels (or color planes) means that the first thing we increment through is the color channels of the current pixel, then through pixels, i.e. for interleaved RGB data, the data is ordered R1, G1, B1, R2, G2, B2..., where the numbers index pixels. <strong>De-interleaved</strong> data seperates the color planes so that we first increment through all the pixels of the first color plane before moving to the next color plane, i.e. we would go through R1, R2, R3..., G1, G2, G3,...., B1, B2, B3.</p> <p> I'll continue posting new conversions here as I find need for them in my own work, but in the meantime, if you don't see the exact conversion here that you want, the ones I've provided should at least help a bit in figuring out how to do your own, and you can always chain multiple conversions together.</p> <p> </p> <h2>MATLAB to RGB</h2> <p><strong>...or column-major de-interleaved RGB to row-major interleaved RGB. </strong></p> <p>This may not be the most apt name for this conversion, but here's the idea. I was writing a MEX file so that I could call some C++ image processing code from within MATLAB. That code was working with interleaved RGB data in row-major order. However, mex files receive inputs from MATLAB as <a href="http://www.mathworks.com/help/techdoc/apiref/mxarray.html" target="_blank">mxArrays</a>, which <a href="http://www.mathworks.com/support/tech-notes/1600/1605.html#mxArray" target="_blank">use column-major</a> de-interleaved data. The column major ordering of MATLAB's data is a throwback to when it was originally written in Fortran.</p> <p> </p> <p>So, before using the data passed from MATLAB, it needs to be rearranged. This can be done as follows, where I'm assuming there could be multiple input images, indexed by <em>int img</em>. Also note that since we don't necessarily know the data type of the input ahead of time, I've included a check for this, which changes the cast of the input data pointer so it gets dereferenced correctly. Here I'm just allowing for <em>double</em> or <em>uint8</em>.</p> <p> </p> <p> </p> <p> </p> <p></p><div class="geshifilter"><pre class="cpp geshifilter-cpp" style="font-family:monospace;"><span style="color: #666666;">// Make array to hold rearranged data </span> pInput_RGB <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> <span style="color: #0000ff;">char</span><span style="color: #008000;">[</span>height<span style="color: #000040;">*</span>width<span style="color: #000040;">*</span>depth<span style="color: #008000;">]</span><span style="color: #008080;">;</span> <span style="color: #666666;">// Get pointer to input data </span> <span style="color: #0000ff;">double</span> <span style="color: #000040;">*</span>mxPtr <span style="color: #000080;">=</span> mxGetPr<span style="color: #008000;">(</span>prhs<span style="color: #008000;">[</span>img<span style="color: #008000;">]</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span> <span style="color: #666666;">// img indexes input images </span> <span style="color: #666666;">//Rearrange data from MATLAB's column-major, de-interleaved RGB order to C-standard row-major interleaved RGB order: </span> <span style="color: #0000ff;">int</span> idx_RGB_RC<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> <span style="color: #666666;">// indexes target data format </span> <span style="color: #0000ff;">int</span> idx_CR_RGB<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> <span style="color: #666666;">// indexes MATLAB's format (column, row, color channel) </span> <span style="color: #666666;">// Don't know ahead of time the data type of input. Will accept double or uint8 </span> <span style="color: #0000ff;">if</span><span style="color: #008000;">(</span>mxGetClassID<span style="color: #008000;">(</span>prhs<span style="color: #008000;">[</span>img<span style="color: #008000;">]</span><span style="color: #008000;">)</span><span style="color: #000080;">==</span>mxDOUBLE_CLASS<span style="color: #008000;">)</span><span style="color: #008000;">{</span> <span style="color: #666666;">// Cast incoming data ptr to double </span> <span style="color: #0000ff;">for</span><span style="color: #008000;">(</span>j<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> j<span style="color: #000080;">&lt;</span>height<span style="color: #008080;">;</span> j<span style="color: #000040;">++</span><span style="color: #008000;">)</span><span style="color: #008000;">{</span> <span style="color: #0000ff;">for</span><span style="color: #008000;">(</span>i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i<span style="color: #000080;">&lt;</span>width<span style="color: #008080;">;</span> i<span style="color: #000040;">++</span><span style="color: #008000;">)</span><span style="color: #008000;">{</span> <span style="color: #0000ff;">for</span><span style="color: #008000;">(</span>k<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> k<span style="color: #000080;">&lt;</span>depth<span style="color: #008080;">;</span> k<span style="color: #000040;">++</span><span style="color: #008000;">)</span><span style="color: #008000;">{</span> idx_RGB_RC <span style="color: #000080;">=</span> <span style="color: #008000;">(</span>j<span style="color: #000040;">*</span>width<span style="color: #000040;">*</span>depth<span style="color: #008000;">)</span><span style="color: #000040;">+</span><span style="color: #008000;">(</span>i<span style="color: #000040;">*</span>depth<span style="color: #008000;">)</span><span style="color: #000040;">+</span>k<span style="color: #008080;">;</span> idx_CR_RGB <span style="color: #000080;">=</span> <span style="color: #008000;">(</span>k<span style="color: #000040;">*</span>height<span style="color: #000040;">*</span>width<span style="color: #008000;">)</span><span style="color: #000040;">+</span><span style="color: #008000;">(</span>i<span style="color: #000040;">*</span>height<span style="color: #008000;">)</span><span style="color: #000040;">+</span>j<span style="color: #008080;">;</span> <span style="color: #008000;">(</span><span style="color: #008000;">(</span><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span><span style="color: #008000;">)</span>pInput_RGB<span style="color: #008000;">)</span><span style="color: #008000;">[</span>idx_RGB_RC<span style="color: #008000;">]</span> <span style="color: #000080;">=</span> <span style="color: #008000;">(</span><span style="color: #0000ff;">char</span><span style="color: #008000;">)</span><span style="color: #008000;">(</span><span style="color: #008000;">(</span> <span style="color: #008000;">(</span> <span style="color: #008000;">(</span><span style="color: #0000ff;">double</span><span style="color: #000040;">*</span><span style="color: #008000;">)</span><span style="color: #008000;">(</span>mxGetPr<span style="color: #008000;">(</span>prhs<span style="color: #008000;">[</span>img<span style="color: #008000;">]</span><span style="color: #008000;">)</span><span style="color: #008000;">)</span> <span style="color: #008000;">)</span> <span style="color: #008000;">[</span>idx_CR_RGB<span style="color: #008000;">]</span><span style="color: #008000;">)</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span> <span style="color: #008000;">}</span> <span style="color: #008000;">}</span> <span style="color: #008000;">}</span> <span style="color: #008000;">}</span> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">(</span>mxGetClassID<span style="color: #008000;">(</span>prhs<span style="color: #008000;">[</span>img<span style="color: #008000;">]</span><span style="color: #008000;">)</span><span style="color: #000080;">==</span>mxUINT8_CLASS<span style="color: #008000;">)</span><span style="color: #008000;">{</span> <span style="color: #666666;">// Cast incoming data ptr to char </span> <span style="color: #0000ff;">for</span><span style="color: #008000;">(</span>j<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> j<span style="color: #000080;">&lt;</span>height<span style="color: #008080;">;</span> j<span style="color: #000040;">++</span><span style="color: #008000;">)</span><span style="color: #008000;">{</span> <span style="color: #0000ff;">for</span><span style="color: #008000;">(</span>i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i<span style="color: #000080;">&lt;</span>width<span style="color: #008080;">;</span> i<span style="color: #000040;">++</span><span style="color: #008000;">)</span><span style="color: #008000;">{</span> <span style="color: #0000ff;">for</span><span style="color: #008000;">(</span>k<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> k<span style="color: #000080;">&lt;</span>depth<span style="color: #008080;">;</span> k<span style="color: #000040;">++</span><span style="color: #008000;">)</span><span style="color: #008000;">{</span> idx_RGB_RC <span style="color: #000080;">=</span> <span style="color: #008000;">(</span>j<span style="color: #000040;">*</span>width<span style="color: #000040;">*</span>depth<span style="color: #008000;">)</span><span style="color: #000040;">+</span><span style="color: #008000;">(</span>i<span style="color: #000040;">*</span>depth<span style="color: #008000;">)</span><span style="color: #000040;">+</span>k<span style="color: #008080;">;</span> idx_CR_RGB <span style="color: #000080;">=</span> <span style="color: #008000;">(</span>k<span style="color: #000040;">*</span>height<span style="color: #000040;">*</span>width<span style="color: #008000;">)</span><span style="color: #000040;">+</span><span style="color: #008000;">(</span>i<span style="color: #000040;">*</span>height<span style="color: #008000;">)</span><span style="color: #000040;">+</span>j<span style="color: #008080;">;</span> <span style="color: #008000;">(</span><span style="color: #008000;">(</span><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span><span style="color: #008000;">)</span>pInput_RGB<span style="color: #008000;">)</span><span style="color: #008000;">[</span>idx_RGB_RC<span style="color: #008000;">]</span> <span style="color: #000080;">=</span> <span style="color: #008000;">(</span><span style="color: #0000ff;">char</span><span style="color: #008000;">)</span><span style="color: #008000;">(</span><span style="color: #008000;">(</span> <span style="color: #008000;">(</span> <span style="color: #008000;">(</span><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span><span style="color: #008000;">)</span><span style="color: #008000;">(</span>mxGetPr<span style="color: #008000;">(</span>prhs<span style="color: #008000;">[</span>img<span style="color: #008000;">]</span><span style="color: #008000;">)</span><span style="color: #008000;">)</span> <span style="color: #008000;">)</span> <span style="color: #008000;">[</span>idx_CR_RGB<span style="color: #008000;">]</span><span style="color: #008000;">)</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span> <span style="color: #008000;">}</span> <span style="color: #008000;">}</span> <span style="color: #008000;">}</span> <span style="color: #008000;">}</span></pre></div> <p> </p> <h2>RGB to ARGB</h2> <p>Some publicly released research code I was using recently required images stored in an unusual integer ARGB format where each pixel was represented by a single integer (4 bytes); bytes two through four were the RGB channels, and the first byte was an (unused as it turns out) <a href="http://en.wikipedia.org/wiki/Alpha_compositing" target="_blank">alpha channel</a>. This is of course basically the more common <a href="http://en.wikipedia.org/wiki/RGBA_color_space" target="_blank">RGBA</a> format, but with the alpha channel moved to first place for some reason.</p> <p> </p> <p>Anyway, the conversion is pretty straightforward; you need to create space for the converted data, then use char pointers to access each of the four bytes making up a pixel individually. In the following snippet I've assumed the input is accessed by a <em>char </em>pointer <em>pInput_RGB</em>, the output is an <em>unsigned int </em>pointer <em>pInput_ARGB</em>. I've also just hard-coded the fact that there are four channels in the ARGB format.</p> <p> </p> <p></p><div class="geshifilter"><pre class="cpp geshifilter-cpp" style="font-family:monospace;"><span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">int</span><span style="color: #000040;">*</span> pInput_ARGB <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> <span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">int</span><span style="color: #008000;">[</span>height<span style="color: #000040;">*</span>width<span style="color: #008000;">]</span><span style="color: #008080;">;</span>   <span style="color: #666666;">// Convert from RGB to ARGB:</span> <span style="color: #0000ff;">int</span> idx_RGB<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span>, idx_ARGB<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">for</span><span style="color: #008000;">(</span>j<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> j<span style="color: #000080;">&lt;</span>height<span style="color: #008080;">;</span> j<span style="color: #000040;">++</span><span style="color: #008000;">)</span><span style="color: #008000;">{</span> <span style="color: #0000ff;">for</span><span style="color: #008000;">(</span>i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i<span style="color: #000080;">&lt;</span>width<span style="color: #008080;">;</span> i<span style="color: #000040;">++</span><span style="color: #008000;">)</span><span style="color: #008000;">{</span> <span style="color: #0000ff;">for</span><span style="color: #008000;">(</span>k<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> k<span style="color: #000080;">&lt;</span>depth<span style="color: #008080;">;</span> k<span style="color: #000040;">++</span><span style="color: #008000;">)</span><span style="color: #008000;">{</span> idx_RGB <span style="color: #000080;">=</span> <span style="color: #008000;">(</span>j<span style="color: #000040;">*</span>width<span style="color: #000040;">*</span>depth<span style="color: #008000;">)</span><span style="color: #000040;">+</span><span style="color: #008000;">(</span>i<span style="color: #000040;">*</span>depth<span style="color: #008000;">)</span><span style="color: #000040;">+</span>k<span style="color: #008080;">;</span> idx_ARGB <span style="color: #000080;">=</span> <span style="color: #008000;">(</span>j<span style="color: #000040;">*</span>width<span style="color: #000040;">*</span><span style="color: #0000dd;">4</span><span style="color: #008000;">)</span><span style="color: #000040;">+</span><span style="color: #008000;">(</span>i<span style="color: #000040;">*</span><span style="color: #0000dd;">4</span><span style="color: #008000;">)</span><span style="color: #000040;">+</span>k<span style="color: #000040;">+</span><span style="color: #0000dd;">1</span><span style="color: #008080;">;</span> <span style="color: #008000;">(</span><span style="color: #008000;">(</span><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span><span style="color: #008000;">)</span>pInput_ARGB<span style="color: #008000;">)</span><span style="color: #008000;">[</span>idx_ARGB<span style="color: #008000;">]</span> <span style="color: #000080;">=</span> <span style="color: #008000;">(</span><span style="color: #008000;">(</span><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span><span style="color: #008000;">)</span>pInput_RGB<span style="color: #008000;">)</span><span style="color: #008000;">[</span>idx_RGB<span style="color: #008000;">]</span><span style="color: #008080;">;</span> <span style="color: #008000;">}</span> <span style="color: #008000;">}</span> <span style="color: #008000;">}</span></pre></div> <p> </p> <p> </p> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/simonsilk" typeof="schema:Person" property="schema:name" datatype="">SimonSilk</span></span> <span class="field field--name-created field--type-created field--label-hidden">Sun, 03/20/2011 - 23:51</span> <div class="field field--name-tags field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix field__items"> <div class="field__item"><a href="/category/tags/snippet" hreflang="en">Snippet</a></div> </div> <div class="field field--name-category field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix field__items"> <div class="field__item"><a href="/category/category/image-processing" hreflang="en">Image Processing</a></div> <div class="field__item"><a href="/category/category/programming" hreflang="en">Programming</a></div> </div> <section class="field field--name-comment field--type-comment field--label-above comment-wrapper"> <h2 class="title comment-form__title">Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=22&amp;2=comment&amp;3=comment" token="8G-0ziIYgIKVNZP_lsiweU7U_jtelpkeubzWPKGyBMY"></drupal-render-placeholder> </section> Mon, 21 Mar 2011 02:51:54 +0000 SimonSilk 22 at http://simonsilk.com Debugging Blue Screen of Death (BSOD) problems http://simonsilk.com/content/debugging-blue-screen-death-bsod-problems <span class="field field--name-title field--type-string field--label-hidden">Debugging Blue Screen of Death (BSOD) problems</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>The dreaded Blue Screen of Death (BSOD) has existed at least as long as Windows, and baffles even fairly advanced computer users. It is usually triggered by low-level errors in the CPU, which in turn are usually caused by driver problems (e.g. illegal pointer references and such) or hardware problems (e.g. deffective RAM or CPU overheating). Usually the errors listed are not very descriptive, just one of the problems in actually making use of them. Whenever I've begun experience frequent BSODs, I've always just formatted my computer and reinstalled Windows, thinking that whatever is happening is probably a software or driver issue so obscure I'd never track it down. However, during the most recent outburst of BSODs on my new laptop (a 10 month old Dell), I decided to take a serious crack at analyzing the BSOD details.</p> <p> </p> <p class="rtecenter"><img alt="Blue Screen of Death" data-entity-type="" data-entity-uuid="" src="http://upload.wikimedia.org/wikipedia/commons/a/a8/Windows_XP_BSOD.png" style="width: 320px; height: 240px;" /></p> <p> </p> <!--break--><p> </p> <p>What follows is an outline of what I did, including the results. This is not meant to be an extensive debugging guide but rather a mix of general techniques and specific steps that will likely shed a little more light on the situation. Note that the instructions are all written for Windows 7 (specifically Professional x64), but should extend easily to at least Windows XP.</p> <p> </p> <h2>My Problem</h2> <p>My BSOD problem was encountered on a 10 month old Dell Inspiron 1564 with a Core i3-m330 processor, 4 GB RAM, 500GB HDD, 1GB ATI Radeon HD4330, running Windows 7 Pro 64bit (from MSDNAA). My last clean install of Windows was about 8 months prior to the BSODs beginning, and they in fact started immediately after I flew with my laptop though it now looks like this was pure coincidence.</p> <p> </p> <p>I began encountering BSODs on a daily basis, usually within 1-2 hours of reboot, sometimes in as little as 5 mins. There was no clear correlation with any particular program; I uninstalled a couple of recently installed programs and printer drivers to no avail. Sometimes a BSOD seemed to follow an event, like it would happen as I opened a new tab in Firefox, other times I could reboot, do nothing, and get one just with my computer sitting idle for a while.</p> <p> </p> <p>I'll return to the saga of my BSODs throughout this post.</p> <p> </p> <h2>Hardware versus Software BSODs</h2> <p>The most common explanation for BSODs I've seen in online forums is defective RAM, regardless of the actual BSOD error codes. I suspect that in reality RAM is rarely the cause, particularly because in most cases, people are experiencing them on a computer that has previously worked fine for a long time (months to years); defects in RAM and other HW are likely to be discovered very early in your computer's life span. Test solutions recommended are to either run Windows' memory diagnostics overnight or Memtest 86. I tried both and everything came out clean.</p> <p> </p> <p>A quick test that can largely rule out hardware issues if it passes is to simply run your computer in Safe Mode for a while. For example, if you're reliably getting a BSOD within 1-2 hours run time in normal mode, reboot into Safe Mode (Windows should give you the option after a reboot after a BSOD). Try Safe Mode with Networking. This will allow you to do most tasks (e.g. internet browsing and such) in the meantime. In this mode, try using your computer as normally as you can, and for way longer than it usually takes to hit a BSOD. If the problem is defective RAM or CPU overheating or some other HW issue, it should still crop up in Safe Mode. If you can run in Safe Mode indefinitely and not have problems, this is a good indication (though not proof) that your problem is software related, and specifically related to one or more drivers or background programs that are disabled in Safe Mode.</p> <p> </p> <h2>Dump Files</h2> <p>So, if the Safe Mode test passes, the next thing you want to try is analyzing the Windows "Dump Files." When a BSOD occurs, Windows saves a Dump file to disk before shutting down. This is basically a record of some portion of the computer's memory (RAM) right before shutdown and tends to include information about which drivers were loaded, what threads were running, some of the last operations before the crash, etc.</p> <p> </p> <p>There are several different dump file options you can set, as well as options for what Windows does when a BSOD occurs. To change the options, in Windows 7, right click on My Computer, then go <em>Advaced system settings &gt; Advanced &gt; Startup and Recovery &gt; Settings</em> and look under the heading <em>System Failure</em>. You have four things you can adjust:</p> <p> </p> <ul><li><strong>Write an event to the system log</strong>. Checked by default, but not very useful.</li> <li><strong>Automatically restart</strong>. May be useful. By default, Windows reboots after a BSOD. So if your situation is that you frequently come back to your computer and find it has rebooted inexplicably, uncheck this. That way, the BSOD stays on screen until you hit the power button to reboot your computer. This allows you to look at the error codes, but more importantly, lets you know you're getting BSODs as opposed to some other type of reboot (e.g. automatic SW update resets).</li> <li><strong>Write Debugging information</strong>. This is the important option. The options are <em>none</em> (no dump file written), <em>Kernel memory dump</em> (a minimal dump file is written), or <em>Small memory dump</em> (more detailed). Set this to Small memory dump. You can also set an alternate location for the dump files, but the default of <em>%SystemRoot%\Minidump</em> is fine. If you don't know where this leads, just click on the Windows Start button and paste this into the search field; this will open a file browser at that location. </li> </ul><p> </p> <p>Now, the next time you get a BSOD, Windows will save a dump file.</p> <p> </p> <p>Note: for my problem, I was not able to diagnose it based on the Kernel dump file, but after changing to Small memory dump, I got enough info to diagnose. Also, in some versions of Windows there may be an option for full memory dump; this is not recommended as it saves your entire RAM to disk, i.e. for my computer, this could take up to 4GB of disk space per dump file.</p> <p> </p> <h3><span id="cke_bm_100S" style="display: none;"> </span><span id="cke_bm_101S" style="display: none;"> </span><span id="cke_bm_98S" style="display: none;"> </span><span id="cke_bm_99S" style="display: none;"> </span></h3> <h2>Analyzing Dump Files<span id="cke_bm_101E" style="display: none;"> </span><span id="cke_bm_100E" style="display: none;"> </span><span id="cke_bm_99E" style="display: none;"> </span><span id="cke_bm_98E" style="display: none;"> </span></h2> <p>Once you have a record of what happened right before a BSOD in the form of a dump file, you want to "read" this file. Unfortunately, these can't be read in a normal text viewer so you need to install a BSOD reader of some kind. Two popular options are WinDdg and Blue Screen View. I used WinDbg.</p> <p> </p> <p>WinDbg is part of the Microsoft Windows SDK, and you can get it <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=6b6c21d2-2006-4afa-9702-529fa782d63b&amp;displaylang=en" target="_blank">here</a>. If that link doesn't work, search for Microsoft Windows SDK and find a version compatible with your version of Windows. You can find basic installation instructions <a href="http://forums.majorgeeks.com/showthread.php?t=35246" target="_blank">here</a>. Those tell you how to install and configure WinDbg so that it can access the necessary debugging symbols online. Note that you probably won't be able to install it in Safe Mode in Windows 7; I tried this and failed, so you need to reboot into full mode at least to do the install. If you can't run in full mode long enough to even install the SDK, you may want to try Blue Screen View instead.</p> <p> </p> <p>More detailed instructions on using WinDbg are available <a href="http://forums.majorgeeks.com/showthread.php?t=35246" target="_blank">here</a>, but the basic steps are as follows:</p> <ul><li>Once WinDbg is installed, open it via <em>Start &gt; All Programs &gt; Debugging Tools for Windows &gt; WinDbg</em>.</li> <li>Choose <em>File &gt; Symbol File Path</em> and enter "SRV*c:\symbols*<a href="http://msdl.microsoft.com/download/symbols">http://msdl.microsoft.com/download/symbols</a>" (without the quotes).</li> <li>Now open your minidump file by choosing <em>File &gt; Open Crash Dump</em>. Remember that the location is <em>%SystemRoot%\Minidump</em> and you can type this directly into the File name field to go there. Also notice the naming convention of <em>mmddyy-xxxxx-xx.dmp</em> which should make it clear what is your most recent dump file.</li> <li>Choose no to saving workspace.</li> </ul><p> </p> <p>Now WinDbg will show you some output including a BugCheck code and a "Probably caused by" field.</p> <p> </p> <p>In my case the output looks like:</p> <p> </p> <blockquote><p><em>BugCheck 7F, {8, 80050031, 6f8, fffff80003249ec0}</em></p> <p>Unable to load image aswTdi.SYS, Win32 error 0n2<br /> *** WARNING: Unable to verify timestamp for aswTdi.SYS<br /> *** ERROR: Module load completed but symbols could not be loaded for aswTdi.SYS<br /> Probably caused by : NETIO.SYS ( NETIO!CompareSecurityContexts+6a )</p> </blockquote> <p> </p> <p>You can click the <em>analyze -v</em> link or type that string into the field at the bottom of the debug window to get verbose output (nerd speak for more details). Mine looks like:</p> <p> </p> <p><em>Debugging Details:<br /> ------------------</em></p> <p>BUGCHECK_STR:  0x7f_8</p> <p>CUSTOMER_CRASH_COUNT:  1</p> <p>DEFAULT_BUCKET_ID:  VISTA_DRIVER_FAULT</p> <p>PROCESS_NAME:  System</p> <p>CURRENT_IRQL:  2</p> <p>LAST_CONTROL_TRANSFER:  from fffff80003280ca9 to fffff80003281740</p> <p>STACK_TEXT:  <br /> (lots of stack text here)</p> <p>STACK_COMMAND:  kb</p> <p>FOLLOWUP_IP:<br /> NETIO!CompareSecurityContexts+6a<br /> fffff880`0154dc5a 448b442470      mov     r8d,dword ptr [rsp+70h]</p> <p>SYMBOL_STACK_INDEX:  4</p> <p>SYMBOL_NAME:  NETIO!CompareSecurityContexts+6a</p> <p>FOLLOWUP_NAME:  MachineOwner</p> <p>MODULE_NAME: NETIO</p> <p>IMAGE_NAME:  NETIO.SYS</p> <p>DEBUG_FLR_IMAGE_TIMESTAMP:  4bbe946f</p> <p>FAILURE_BUCKET_ID:  X64_0x7f_8_NETIO!CompareSecurityContexts+6a</p> <p>BUCKET_ID:  X64_0x7f_8_NETIO!CompareSecurityContexts+6a</p> <p> </p> <p>If you've read this far, and looked at some other How-Tos about debugging BSODs, you're probably wondering what new points I'm bringing to the table, and here they are (don't get too excited). Most of the guides I've seen so far at this point either direct to you to a laundry list of stop codes and their supposed meanings (usually very ambiguous or just meaningless to anyone other than computer HW engineers), or they'll just tell you that any bug check code means RAM errors and you should start swapping your RAM in and out of various slots and other computers to test it.  </p> <p> </p> <p>What I recommend you do at this point is copy the Bugcheck string and some or all of the probable cause string and just google it. Chances are someone else, or in fact many other people have already had the same problem and come to some concensus about its meaning in forums, which will point you to the problem SW or HW.</p> <p> </p> <p>For my error, I googled "0x7f_8 NETIO.SYS" without quotes. I immediately found many forums posts with the same problem, and they all pointed towards ZoneAlarm as the culprit and recommended uninstalling it. I did so and haven't had a BSOD since (about 4 days and counting now).</p> <p> </p> <h2>Conclusion</h2> <p>So, to quickly review, if you're having frequent BSODs, a good plan of attack is:</p> <ul><li>Try running in Safe Mode with Networking. If you seem to be able to do so indefinitely, you're probably (though not definitely) not looking at a HW issue. If you still get BSODs, dial it down another notch by running in just Safe Mode.</li> <li>Turn on Small memory dump saving</li> <li>Get WinDbg and analyze your dump files. If you have several or many, analyze a handful of recent ones to see if the errors are consistent or not.</li> <li>Google the stop code and probable cause strings that WingDbg gives you to see if there's a consensus in forums about the guilty driver/ SW/ device, and try uninstalling/ disabling/ removing said item. If you don't get a good result with your search, try adding or removing some of the details from WinDbg.</li> </ul><p> </p> <p>Thanks to user Adrynalyne at Majorgeeks for <a href="http://forums.majorgeeks.com/showthread.php?t=35246" target="_blank">this post</a> which provided most of the details on installing and configuring WinDbg.</p> <p> </p> <p>Hope that helps!</p> <p> </p> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/simonsilk" typeof="schema:Person" property="schema:name" datatype="">SimonSilk</span></span> <span class="field field--name-created field--type-created field--label-hidden">Sun, 03/13/2011 - 00:01</span> <div class="field field--name-tags field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix field__items"> <div class="field__item"><a href="/category/tags/windows-7" hreflang="en">Windows 7</a></div> <div class="field__item"><a href="/category/tags/debugging" hreflang="en">Debugging</a></div> <div class="field__item"><a href="/category/tags/computer-repair" hreflang="en">Computer Repair</a></div> </div> <section class="field field--name-comment field--type-comment field--label-above comment-wrapper"> <h2 class="title comment-form__title">Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=13&amp;2=comment&amp;3=comment" token="IpQiXavlekgUkoMY55I96KcK_vUoClR5uCQ4Y4laa90"></drupal-render-placeholder> </section> Sun, 13 Mar 2011 04:01:37 +0000 SimonSilk 13 at http://simonsilk.com Media Attention for University of Ottawa Image-Based Rendering Project http://simonsilk.com/content/simonsilk/2011-mar/media-attention-university-ottawa-image-based-rendering-project <span class="field field--name-title field--type-string field--label-hidden">Media Attention for University of Ottawa Image-Based Rendering Project</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p> For my Master's research, I'm part of a research team of about 12 students and post-docs, as well as three professors at the University of Ottawa who are working on an NSERC Strategic Project entitled "<span class="il">High</span>-<span class="il">quality</span> <span class="il">acquisition</span> and rendering of image-based models for tele-presence in remote environments." This project received some media attention over the past year, long before I got my site online, so I'm sharing it just a little late.</p> <p>  </p> <h3> <a href="http://www.cbc.ca/spark/2010/12/spark-131-december-19-22-2010/" target="_blank">CBC Spark Interview</a></h3> <p> The project was featured in CBC Radio's program Spark. Meg Wilcox interviewed myself and several other members of the team about our work on the project. You can listen to the full interview (about 10 minutes) <a href="http://www.cbc.ca/spark/2010/12/spark-131-december-19-22-2010/" target="_blank">here</a>. My portion is towards the end, and I talk about High Dynamic Range Imaging and the "So What?" of my work, i.e. what does it do for the end user.</p> <p>  </p> <h3> <a href="http://www2.canada.com/saskatoonstarphoenix/news/story.html?id=8edcb294-699c-4dc4-8c35-c631807fb274&amp;p=1" target="_blank">Ottawa professors look to take Google's Street View to the next level</a></h3> <p> Back in June, the project was featured in the Ottawa Citizen, and several professors and a post-doc student from the project were interviewed. This was story also ran in the National Post and on Canada.com.</p> <p>  </p> <!--break--></div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/simonsilk" typeof="schema:Person" property="schema:name" datatype="">SimonSilk</span></span> <span class="field field--name-created field--type-created field--label-hidden">Thu, 03/03/2011 - 00:20</span> <div class="field field--name-tags field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix field__items"> <div class="field__item"><a href="/category/tags/telepresence" hreflang="en">Telepresence</a></div> <div class="field__item"><a href="/category/tags/research" hreflang="en">Research</a></div> <div class="field__item"><a href="/category/tags/image-based-rendering" hreflang="en">Image Based Rendering</a></div> </div> <div class="field field--name-category field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix field__items"> <div class="field__item"><a href="/category/category/news" hreflang="en">News</a></div> </div> <section class="field field--name-comment field--type-comment field--label-above comment-wrapper"> <h2 class="title comment-form__title">Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=19&amp;2=comment&amp;3=comment" token="qxWv4qHZP5DVri8yNHVDOGyFO3855_xVgGs6v6Fkg1I"></drupal-render-placeholder> </section> Thu, 03 Mar 2011 04:20:26 +0000 SimonSilk 19 at http://simonsilk.com Floating Point Images in OpenCV http://simonsilk.com/content/simonsilk/2011-feb/floating-point-images-opencv <span class="field field--name-title field--type-string field--label-hidden">Floating Point Images in OpenCV</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Working with Floating Point images in <a href="http://opencv.willowgarage.com/wiki/" target="_blank">OpenCV</a> can be tricky, especially if you've so far only worked with 8-bit (uchar) images. In this tutorial, I'll describe how to create a floating point image, how to access and modify it, and how to save it to or load it from disk.</p> <p>There are many scenarios where we might wish to work with floating point pixel values. In my case, I'm working on <a href="http://en.wikipedia.org/wiki/High_dynamic_range_imaging" target="_blank">High Dynamic Range Imaging</a> which inherently deals with floats rather than integer values. A more common scenario is that you want to apply a series of operations to an image in a processing pipeline, and you'd like to maintain high precision throughout, then clamp the values at the end and round to integers. In that case you could take an 8-bit image at the beginning, convert it to 32-bit floats, perform all your operations on it, then convert back to 8-bit at the end so you only have one instance of integer rounding error.</p> <!--break--><h2>Creating Float Images</h2> <p>The first step is to create a floating point image. Since OpenCV 2.0, the catch-all class for images and matrices is the <a href="http://opencv.willowgarage.com/documentation/cpp/core_basic_structures.html#mat" target="_blank">Mat</a>, and the Mat constructor provides you with many different ways to create and/or initialize a Matrix (currently 14 different constructors). Any constructor containing a field for type allows you to directly specify the bit depth for the matrix. For example, at present, the second constructor is <tt class="descname">Mat::Mat(int rows, int cols, int type),</tt>where the type is the OpenCV data type, e.g. CV_8UC3.</p> <p>Bizarrely, I've never seen any documentation where they clearly either outline all the available types, or the syntax to denote a type. Probably it's just really obvious to everyone else. In case you've ever found yourself wondering if some type you're trying to use actually exists, here's the pattern. They all start with "CV_" which is followed by the bit-depth (number of bits per color channel per pixel), followed by the initial of the actual data type, then 'C' then the number of channels. So, for example, CV_8UC3 denotes an 8-bit Unsigned character (uchar) 3-Channel image; note that this means there are 24 bits per pixels due to there being 3 channels, each having an 8-bit uchar. Similarily, a 4-channel 32-bit floating point image would be denoted by CV_32FC4.If you want to see the full list of available types, they are listed in cxtypes.h. To get there quickly in Visual Studio, type in one type you know exists, like CV_8UC3, then right click on it and choose "Go to Definition."</p> <h2>Populating Your Float Image</h2> <p>Again, there are many ways and reasons to populate an image with float data. In many cases, you may want to start with integer images, convert to floats, perform some operations, then convert back. In my case, I'm generally loading floating point data from disk, then working with it, then writing it back to disk. In either case, once you have your floating point data on hand, you can simply copy it into your Mat as float data, but you do need to be aware of how to properly reference matrix elements, which tripped me up briefly at first.</p> <h2>Accessing Pixel Data</h2> <p>OpenCV's Mat class has a member <em>data</em> which returns a pointer for directly accessing the image data. This pointer is always of type uchar, which is an 8-bit unsigned char, for holding 8-bit integers. If you've already done some iterating through OpenCV matrices, you're probably familiar with the following idea. To access the kth channel of pixel (i,j), in Mat myMat you would do the following:</p> <p></p><div class="geshifilter"><pre class="cpp geshifilter-cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span> x <span style="color: #000080;">=</span> myMat.<span style="color: #007788;">data</span><span style="color: #008000;">[</span> j<span style="color: #000040;">*</span>myMat.<span style="color: #007788;">step</span><span style="color: #008000;">(</span><span style="color: #008000;">)</span> <span style="color: #000040;">+</span> i<span style="color: #000040;">*</span>myMat.<span style="color: #007788;">channels</span> <span style="color: #000040;">+</span> k <span style="color: #008000;">]</span></pre></div> <p>which basically says to offset the data pointer by the current row number times the width of each row plus the current column number times the number of color channels plus the current color channel.</p> <p>The important thing to keep in mind when switching to float images is that <em>step()</em> is measured in bytes. At the same time, C++ pointer offsets are automatically multiplied by the number of bytes that a given data type takes up in memory. For example, on most 32 bit systems, a float takes up 4 bytes in memory. So, offsetting a float pointer by 1 or simply incremementing it will actually add 4 to its address it stores so that it now points at the next float in memory. This is quickly confirmed as follows:</p> <p></p><div class="geshifilter"><pre class="cpp geshifilter-cpp" style="font-family:monospace;"><span style="color: #0000ff;">float</span><span style="color: #000040;">*</span> test <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> <span style="color: #0000ff;">float</span><span style="color: #008000;">[</span><span style="color: #0000dd;">10</span><span style="color: #008000;">]</span><span style="color: #008080;">;</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> test <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span> test<span style="color: #000040;">++</span><span style="color: #008080;">;</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> test <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span></pre></div> <p>Now, remember that step() is given in bytes. This works great when working with uchar images since a uchar takes up a single byte, and therefore offsetting the data pointer by the step width as measured in bytes actually does get you to the same pixel in the next row. However, when you're working with floats, the step() is still measured in bytes, but each entry (a given color channel and pixel) actually takes up however many bytes are needed for a float on your system (4 bytes on mine, and I'll assume that's the case for the rest of this post).</p> <p>Therefore, offsettting a float pointer by step() is going to take you 4 times as far as you want to go. At the same time, the Mat data pointer is always a uchar pointer, so offsetting <em>it </em>by step() <em>is </em>actually going to do what you want, but offsetting it by <em>i*myMat.channels + k</em> will only take you 1/4 as far into the current row as you want.</p> <p>So, in referencing into a float image, you need to either work entirely in bytes then cast the pointer to a float*, or better yet, make use of the Mat member step1(), which returns step()/elemSize(). Why can't you just multiply the number of columns by the number of channels to get the width? Because OpenCV sometimes pads images out to make their width a multiple of four, so this will appear to work in many situations since in practice most images' widths and heights are multiples of four, but this may fail in some cases.</p> <p>So, when referencing data in a float image, you want to do the following:</p> <p></p><div class="geshifilter"><pre class="cpp geshifilter-cpp" style="font-family:monospace;"><span style="color: #0000ff;">float</span> x <span style="color: #000080;">=</span> <span style="color: #008000;">(</span><span style="color: #008000;">(</span><span style="color: #0000ff;">float</span><span style="color: #000040;">*</span><span style="color: #008000;">)</span><span style="color: #008000;">(</span>myMat.<span style="color: #007788;">data</span><span style="color: #008000;">)</span><span style="color: #008000;">)</span><span style="color: #008000;">[</span> j<span style="color: #000040;">*</span>myMat.<span style="color: #007788;">step1</span><span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #000040;">+</span> i<span style="color: #000040;">*</span>myMat.<span style="color: #007788;">channels</span> <span style="color: #000040;">+</span> k<span style="color: #008000;">]</span></pre></div> <p>where what we've done is to first cast the uchar* pointer myMat.data to a float* so that each offset to that pointer will now offset by 4 address units instead of one. We then offset the pointer more or less as we normally would, except using <em>step1()</em> instead of <em>step()</em>. Note that this method will work fine for uchar images as well.</p> <h2>Saving Float Images to Disk</h2> <p>This post has run a little longer than I wanted, so I'll be brief here. OpenCV includes functions to read and write data to XML files, and this works for storing and retrieving float images. Another option if you'd like a really simple format is the <a href="http://netpbm.sourceforge.net/doc/pfm.html" target="_blank">Portable Float Map</a> (PFM) format, which is basically a float version of <a href="http://netpbm.sourceforge.net/doc/ppm.html" target="_blank">Portable Pixel Maps</a> (PPMs). It's not really standardized yet, but it is supported by a few libraries, and in any case the format's so simple that you can write your own code to read and write it quite quickly. I'll cover this in more detail in a later post, and include a link to said post here at that time.</p> <h2>Conclusion</h2> <p>Working with float images in OpenCV is pretty straightforward as long as you're aware of the difference between offsetting pointers by the number of bytes required versus offsetting them by the number of pointer units required. In the first case, you need to make all offset calculations in bytes, then divide by the size of a matrix element, which may be hard to retrieve in any way other than hard coding because the Mat data pointer is always uchar, so <em>sizeof(myMat.data)</em> is always 1 even if you've made a float image. It's generally easier to work in pointer units. Ultimately, you can do one or the other, but not mix them. In my case, when I started working with float images, I had some code that used step() instead of step1, so when I offset the way I showed at the beginning of this post my code would crash once the vertical index j reached 1/4 of height since step() was increasing my pointer 4 times as much as I wanted.</p> <p>If you make a mistake converting code that currently works with uchar images, you'll likely see one of two behaviours: either your code crashes part way through the matrix, or whatever operation you're performing is only applied to 1/4 of the image. In the first case, you're likely offsetting using step() instead of step1(). In the second case, you're likely not casting the uchar pointer <em>data</em> to a float before offsetting by <em>i*myMat.channels + k</em>.</p> <p>You can read more about the topics covered here in Bradski and Kaehler's <a href="http://oreilly.com/catalog/9780596516130" target="_blank">Learning OpenCV</a>, chapter 2.</p> <p> </p> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/simonsilk" typeof="schema:Person" property="schema:name" datatype="">SimonSilk</span></span> <span class="field field--name-created field--type-created field--label-hidden">Sat, 02/26/2011 - 22:04</span> <div class="field field--name-tags field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix field__items"> <div class="field__item"><a href="/category/tags/programming" hreflang="en">Programming</a></div> <div class="field__item"><a href="/category/tags/opencv" hreflang="en">OpenCV</a></div> </div> <div class="field field--name-category field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix field__items"> <div class="field__item"><a href="/category/category/computer-vision" hreflang="en">Computer Vision</a></div> </div> <section class="field field--name-comment field--type-comment field--label-above comment-wrapper"> <h2 class="title">Comments</h2> <a id="comment-14"></a> <article role="article" data-comment-user-id="0" about="/comment/14" typeof="schema:Comment" class="comment js-comment by-anonymous clearfix"> <span class="hidden new-indicator" data-comment-timestamp="1319714766"></span> <header> <article typeof="schema:Person" about="/user/0" class="profile"> <drupal-render-placeholder callback="flag.link_builder:build" arguments="0=user&amp;1=0&amp;2=following" token="dV8BLmhD339z_wMjaUSDxONyVEf9d6Tb-DESjU5tHGA"></drupal-render-placeholder></article> </header> <div class="comment__content-container"> <nav class="comment__links"><drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=14&amp;1=default&amp;2=en&amp;3=" token="skGpcZFoOquSlGTFo25a2VqyLi62sXtq0hba2qkOIow"></drupal-render-placeholder></nav> <div class="comment__meta"> <span>Submitted by <span rel="schema:author"><span lang="" typeof="schema:Person" property="schema:name" datatype="">Anonymous (not verified)</span></span> Thu, 10/27/2011 - 08:26 <span property="schema:dateCreated" content="2011-10-27T11:26:06+00:00" class="rdf-meta hidden"></span> </span> </div> <h3 property="schema:name" datatype="" class="title"><a href="/comment/14#comment-14" class="permalink" rel="bookmark" hreflang="en">I think maybe using ptr would</a></h3> <div class="comment__content"> <div property="schema:text" class="clearfix text-formatted field field--name-comment-body field--type-text-long field--label-hidden field__item">I think maybe using ptr would be much easier than using data, as this can avoid step</div> </div> </div> </article> <a id="comment-17"></a> <article role="article" data-comment-user-id="0" about="/comment/17" typeof="schema:Comment" class="comment js-comment by-anonymous clearfix"> <span class="hidden new-indicator" data-comment-timestamp="1352936427"></span> <header> <article typeof="schema:Person" about="/user/0" class="profile"> <drupal-render-placeholder callback="flag.link_builder:build" arguments="0=user&amp;1=0&amp;2=following" token="dV8BLmhD339z_wMjaUSDxONyVEf9d6Tb-DESjU5tHGA"></drupal-render-placeholder></article> </header> <div class="comment__content-container"> <nav class="comment__links"><drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=17&amp;1=default&amp;2=en&amp;3=" token="5isjmYk2KTZEcK1HtfaH0Ku5AQT2eBHTBu8nta57bes"></drupal-render-placeholder></nav> <div class="comment__meta"> <span>Submitted by <span rel="schema:author"><span lang="" typeof="schema:Person" property="schema:name" datatype="">Anonymous (not verified)</span></span> Wed, 11/14/2012 - 19:40 <span property="schema:dateCreated" content="2012-11-14T23:40:27+00:00" class="rdf-meta hidden"></span> </span> </div> <h3 property="schema:name" datatype="" class="title"><a href="/comment/17#comment-17" class="permalink" rel="bookmark" hreflang="en">Saving floating point images with OpenEXR format</a></h3> <div class="comment__content"> <div property="schema:text" class="clearfix text-formatted field field--name-comment-body field--type-text-long field--label-hidden field__item">Here is a way I have been able to export 32-bit floating point monochrome images from OpenCV ver 2.4.1. My OS is Ubuntu 12.04 and I like to use ImageJ as an interactive image-analysis tool. Your situation is probably different but this can be a guide. (1) Download ImageMagick source, configure for hdr, and install. I used: tar xvfz ImageMagick-6.8.0-4.tar.gz cd ImageMagick-6.8.0-4/ ./configure --enable-hdri --prefix=/../usr make sudo apt-get remove imagemagick sudo make install (2) Install libopenexr if needed (it was already ther on my 12.04) (3) In openCV, use cv::imwrite("testfile.exr", image) (4) at command line use convert -depth 32 -separate -channel L -define quantum:format=floating-point testfile.exr testfile.tiff ; testfile.tiff can be read by ImageJ. P.S.: Sorry, I couldn't figure out what markup this blog wants to make the text more readable.</div> </div> </div> </article> <a id="comment-38"></a> <article role="article" data-comment-user-id="0" about="/comment/38" typeof="schema:Comment" class="comment js-comment by-anonymous clearfix"> <span class="hidden new-indicator" data-comment-timestamp="1363970681"></span> <header> <article typeof="schema:Person" about="/user/0" class="profile"> <drupal-render-placeholder callback="flag.link_builder:build" arguments="0=user&amp;1=0&amp;2=following" token="dV8BLmhD339z_wMjaUSDxONyVEf9d6Tb-DESjU5tHGA"></drupal-render-placeholder></article> </header> <div class="comment__content-container"> <nav class="comment__links"><drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=38&amp;1=default&amp;2=en&amp;3=" token="Kp71kBs1el410NhBpfenh3PMri37GPQSw9Csso9QNSI"></drupal-render-placeholder></nav> <div class="comment__meta"> <span>Submitted by <span rel="schema:author"><span lang="" typeof="schema:Person" property="schema:name" datatype="">Anonymous (not verified)</span></span> Fri, 03/22/2013 - 13:44 <span property="schema:dateCreated" content="2013-03-22T16:44:41+00:00" class="rdf-meta hidden"></span> </span> </div> <h3 property="schema:name" datatype="" class="title"><a href="/comment/38#comment-38" class="permalink" rel="bookmark" hreflang="en">error</a></h3> <div class="comment__content"> <div property="schema:text" class="clearfix text-formatted field field--name-comment-body field--type-text-long field--label-hidden field__item">You forgot to use myMat.channels(). Otherwise it gives an error with OpenCV 2.4.4</div> </div> </div> </article> <h2 class="title comment-form__title">Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=18&amp;2=comment&amp;3=comment" token="nAj2keyfEt4_0fyhSgew93ONC0o92AbyNwt55od7XmU"></drupal-render-placeholder> </section> Sun, 27 Feb 2011 02:04:13 +0000 SimonSilk 18 at http://simonsilk.com