<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tanner Helland (dot) Com&#187; Programming</title>
	<atom:link href="http://www.tannerhelland.com/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.tannerhelland.com</link>
	<description>Home of the award-winning author, VG composer, and programmer</description>
	<lastBuildDate>Mon, 23 Aug 2010 03:43:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Stained Glass Effect (using VB6 and GIMP)</title>
		<link>http://www.tannerhelland.com/2306/stained-glass-image-effect/</link>
		<comments>http://www.tannerhelland.com/2306/stained-glass-image-effect/#comments</comments>
		<pubDate>Wed, 23 Jun 2010 00:26:42 +0000</pubDate>
		<dc:creator>Tanner</dc:creator>
				<category><![CDATA[Graphics Code]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[GIMP]]></category>
		<category><![CDATA[post-processing]]></category>
		<category><![CDATA[randomizing]]></category>
		<category><![CDATA[stained glass]]></category>

		<guid isPermaLink="false">http://www.tannerhelland.com/?p=2306</guid>
		<description><![CDATA[I wanted to title this article "a novel method for matrix randomization using polygons and custom differential post-processing blending"... but that was a bit long, even for me...]]></description>
			<content:encoded><![CDATA[<p>I wanted to title this article &#8220;<em>a novel method for matrix randomization using polygons and custom differential post-processing blending</em>&#8220;&#8230; but that was a bit long, even for me.</p>
<p>Why such a complex title?</p>
<p>It all started with a strange idea I had today.  I was thinking of common ways to randomize image data (don&#8217;t ask why), and it struck me that the most common randomization method &#8211; varying RGB data of single pixels &#8211; is not the most interesting way to go about it.   Why not use lines, triangles, or other polygons to randomize an image?   How would that look?</p>
<p>To test my theory, I wrote a quick program that selects two random pixels in an image, averages their colors, then draws a line of that averaged color between the two points.  When repeated over and over again, such an algorithm leads to some interesting effects&#8230;</p>
<div id="attachment_2313" class="wp-caption aligncenter" style="width: 646px"><a  rel="attachment wp-att-2313" href="http://www.tannerhelland.com/2306/stained-glass-image-effect/gow3_original-2/"><img class="size-full wp-image-2313" title="GoW3_original" src="http://www.tannerhelland.com/wp-content/uploads/2010/06/GoW3_original1.jpg" alt="" width="636" height="333" /></a><p class="wp-caption-text">I started with this God of War 3 image...</p></div>
<div id="attachment_2314" class="wp-caption aligncenter" style="width: 646px"><a  rel="attachment wp-att-2314" href="http://www.tannerhelland.com/2306/stained-glass-image-effect/gow3_lines_30/"><img class="size-full wp-image-2314" title="GoW3_lines_30" src="http://www.tannerhelland.com/wp-content/uploads/2010/06/GoW3_lines_30.jpg" alt="" width="636" height="333" /></a><p class="wp-caption-text">...and got this  (100,000 iterations of lines with max length 42).</p></div>
<div id="attachment_2315" class="wp-caption aligncenter" style="width: 646px"><a  rel="attachment wp-att-2315" href="http://www.tannerhelland.com/2306/stained-glass-image-effect/gow3_lines_60/"><img class="size-full wp-image-2315" title="GoW3_lines_60" src="http://www.tannerhelland.com/wp-content/uploads/2010/06/GoW3_lines_60.jpg" alt="" width="636" height="333" /></a><p class="wp-caption-text">Here&#39;s the same image, but with lines of max length 85.</p></div>
<p>Kinda cool.  I&#8217;m not sure what to call this effect&#8230; although it looks &#8220;furry&#8221; to me.  Should we invent a new word &#8211; <em>furrification</em>?</p>
<p>Once I had lines working, my next curiosity involved polygons.  Here&#8217;s the same picture, but with triangle randomization:</p>
<div id="attachment_2316" class="wp-caption aligncenter" style="width: 646px"><a  rel="attachment wp-att-2316" href="http://www.tannerhelland.com/2306/stained-glass-image-effect/gow3_triangles_30/"><img class="size-full wp-image-2316" title="GoW3_triangles_30" src="http://www.tannerhelland.com/wp-content/uploads/2010/06/GoW3_triangles_30.jpg" alt="" width="636" height="333" /></a><p class="wp-caption-text">Same parameters as the first line-based randomization above (100,000 iterations, 42 max length).</p></div>
<div id="attachment_2317" class="wp-caption aligncenter" style="width: 646px"><a  rel="attachment wp-att-2317" href="http://www.tannerhelland.com/2306/stained-glass-image-effect/gow3_triangles_60/"><img class="size-full wp-image-2317" title="GoW3_triangles_60" src="http://www.tannerhelland.com/wp-content/uploads/2010/06/GoW3_triangles_60.jpg" alt="" width="636" height="333" /></a><p class="wp-caption-text">Same parameters as the second line-based image above (100,000 iterations, max length 85)</p></div>
<p>This is also a cool effect, especially when you watch it in action.  (The program refreshes the screen every 100 iterations.)</p>
<p>While I didn&#8217;t go to the trouble of implementing additional polygons, the code is primed and ready for it.  In fact, it would be trivial to draw polygons of any segment count.</p>
<p>Once I had my newly randomized images, I decided to pop into GIMP and do a bit of post-processing.  It was then that I realized this could be used to create pretty sweet stained glass images:</p>
<div id="attachment_2318" class="wp-caption aligncenter" style="width: 646px"><a  rel="attachment wp-att-2318" href="http://www.tannerhelland.com/2306/stained-glass-image-effect/gow3-stained-glass-30/"><img class="size-full wp-image-2318" title="GoW3-stained-glass-30" src="http://www.tannerhelland.com/wp-content/uploads/2010/06/GoW3-stained-glass-30.jpg" alt="" width="636" height="333" /></a><p class="wp-caption-text">Sweet!</p></div>
<p>It&#8217;s trivial to create an image like this &#8211; simply open up your base image, then add a triangle randomized copy over the top as a new layer.  Set the layer mode to &#8220;difference&#8221; and bam: stained glass!</p>
<div id="attachment_2319" class="wp-caption aligncenter" style="width: 646px"><a  rel="attachment wp-att-2319" href="http://www.tannerhelland.com/2306/stained-glass-image-effect/gow3-stained-glass-60/"><img class="size-full wp-image-2319" title="GoW3-stained-glass-60" src="http://www.tannerhelland.com/wp-content/uploads/2010/06/GoW3-stained-glass-60.jpg" alt="" width="636" height="333" /></a><p class="wp-caption-text">Same effect, but with a larger triangle size.</p></div>
<p>Other blending modes provide interesting effects &#8211; for example, multiply:</p>
<div id="attachment_2320" class="wp-caption aligncenter" style="width: 646px"><a  rel="attachment wp-att-2320" href="http://www.tannerhelland.com/2306/stained-glass-image-effect/gow3-multiply-30/"><img class="size-full wp-image-2320" title="GoW3-multiply-30" src="http://www.tannerhelland.com/wp-content/uploads/2010/06/GoW3-multiply-30.jpg" alt="" width="636" height="333" /></a><p class="wp-caption-text">Same two images as the first stained glass example - just the blending mode has changed.</p></div>
<p>Anyway, I thought this was an interesting exploration in using a randomized copy of an image as an overlay.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tannerhelland.com/2306/stained-glass-image-effect/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Generating Emboss / Engrave / Relief Filters (in VB6)</title>
		<link>http://www.tannerhelland.com/2225/generating-emboss-engrave-relief-filters-vb6/</link>
		<comments>http://www.tannerhelland.com/2225/generating-emboss-engrave-relief-filters-vb6/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 02:07:18 +0000</pubDate>
		<dc:creator>Tanner</dc:creator>
				<category><![CDATA[Graphics Code]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[emboss]]></category>
		<category><![CDATA[engrave]]></category>
		<category><![CDATA[image processing]]></category>
		<category><![CDATA[relief]]></category>

		<guid isPermaLink="false">http://www.tannerhelland.com/?p=2225</guid>
		<description><![CDATA[Basic <em>emboss</em> and <em>engrave</em> filters are two of the simplest image processing features to implement. Both operate on the same principle - for each pixel, subtract the RGB values of one or more neighboring pixels in a particular direction. This leads to an image where low-contrast areas are all black, while high-contrast areas (edges) are varying colors of brighter intensity. Most emboss/engrave filters add 127 to the RGB values so that uniformly contrasted areas are gray.  I've added a "color" option to my implementation, so you can emboss/engrave an image to any hue. In the Bayonetta example above, the left side of the picture is embossed to something around #81a3fe...]]></description>
			<content:encoded><![CDATA[<div id="attachment_2226" class="wp-caption aligncenter" style="width: 632px"><a  rel="attachment wp-att-2226" href="http://www.tannerhelland.com/2225/generating-emboss-engrave-relief-filters-vb6/bayonetta_emboss/"><img class="size-full wp-image-2226" title="bayonetta_emboss" src="http://www.tannerhelland.com/wp-content/uploads/2010/06/bayonetta_emboss.jpg" alt="" width="622" height="352" /></a><p class="wp-caption-text">Bayonetta is quite possibly the best action game I&#39;ve ever played - yes, even better than God of War III</p></div>
<p>I&#8217;ve had this code ready for months, but I couldn&#8217;t bring myself to post it until I added something more exciting than just &#8220;emboss&#8221; and &#8220;engrave.&#8221;</p>
<p>Today is that day!</p>
<p>First, let me mention what emboss/engrave actually do.  These are two of the simplest image processing filters, and they can be efficiently implemented in pretty much any programming language.  They both operate on the same principle &#8211; for each pixel, subtract the RGB values of one or more neighboring pixels in a particular direction.  This leads to an image where low-contrast areas are all black, while high-contrast areas (edges) are varying colors of brighter intensity.  Most emboss/engrave filters add 127 to the RGB values so that uniformly contrasted areas are gray.  As a bonus feature, I&#8217;ve added a &#8220;color&#8221; option to this code, so you can emboss/engrave an image to any hue.  In the Bayonetta example above, the left side of the picture is embossed to something around #81a3fe.</p>
<p>Relief is a variation on emboss/engrave, where the base color is not artificially generated but is based off the current pixel.  This acts almost like a sharpen filter, but because the filter doesn&#8217;t operate in all directions, it lends the image a more artificial look.  (Hence the &#8220;relief&#8221; moniker &#8211; on certain images, it looks like an image has been chipped out of stone and then painted.)  Try it on a photo &#8211; they tend to work best!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tannerhelland.com/2225/generating-emboss-engrave-relief-filters-vb6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Drawing the Mandelbrot Set / Fractal (in VB6)</title>
		<link>http://www.tannerhelland.com/1494/mandelbrot-vb6/</link>
		<comments>http://www.tannerhelland.com/1494/mandelbrot-vb6/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 03:08:20 +0000</pubDate>
		<dc:creator>Tanner</dc:creator>
				<category><![CDATA[Graphics Code]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Fractals]]></category>
		<category><![CDATA[Mandelbrot Set]]></category>

		<guid isPermaLink="false">http://www.tannerhelland.com/?p=1494</guid>
		<description><![CDATA[Today's very cool project demonstrates a proof of concept implementation for rendering the famed Mandelbrot set (or "Mandelbrot fractal") using VB6.  It's a bit of a feat, since VB6 isn't exactly optimized for recursion-heavy calculations...but you know me.  I love making VB do things it was never meant to do!  :)]]></description>
			<content:encoded><![CDATA[<div id="attachment_1496" class="wp-caption aligncenter" style="width: 518px"><a  rel="attachment wp-att-1496" href="http://www.tannerhelland.com/1494/mandelbrot-vb6/mandelbrot_vb6/"><img class="size-large wp-image-1496" title="Mandelbrot_VB6" src="http://www.tannerhelland.com/wp-content/uploads/2010/03/Mandelbrot_VB6-508x600.png" alt="" width="508" height="600" /></a><p class="wp-caption-text">One possible view of the Mandelbrot set (generated with this project)</p></div>
<p>Today&#8217;s very cool project demonstrates a proof of concept implementation for rendering the famed Mandelbrot set (or &#8220;Mandelbrot fractal&#8221;) using VB6.  It&#8217;s a bit of a feat, since VB6 isn&#8217;t exactly optimized for recursion-heavy calculations&#8230;but you know me.  :)  I love making VB do things it was never meant to do!</p>
<p>I&#8217;m very happy with how the project turned out.  It may not be the fastest or prettiest or most accurate implementation (for example, at very high zoom-in you&#8217;ll start to see noticeable quality degradation), but I&#8217;ve  deliberately kept the project as short and sweet as possible to maximize adaptability and learning potential.</p>
<p>To enhance the experience, I&#8217;ve added several user-controlled options to help you get a feel for how the rendering works.  First is the scroll-bar at the top of the screen, which allows you to preferentially set speed or accuracy as the program&#8217;s objective.  (For those familiar with how the Mandelbrot set works, the scroll bar controls the &#8220;escape time&#8221; of the recursive function.)</p>
<p>Another neat option is a click-and-drag feature that allows you to draw new rendering boundaries.  This makes it simple to zoom as deep as you want into the fractal.</p>
<p>Finally, rather than a drab grayscale rendering, I&#8217;ve chosen a more purplish gradient.  The code can be easily modified to favor another color if you so choose.</p>
<p>The code is reasonably optimized, so a complete view should render within several seconds on most modern hardware.  If speed is a concern, note that the white areas of the image take the longest to process &#8211; so <strong>minimizing</strong> the amount of white you select will <strong>maximize</strong> render speed.  Also, due to the inherent limits of the &#8220;Double&#8221; type in VB6, if you zoom in really, really far the program may lock up.  (Simply click the close button to force-terminate the project if this happens.)</p>
<p>The download link can be found below these sample images.</p>
<div class="captionfull">
<a  rel="attachment wp-att-1499" href="http://www.tannerhelland.com/1494/mandelbrot-vb6/mandelbrot_vb6_4/"><img class="aligncenter size-full wp-image-1499" title="Mandelbrot_VB6_4" src="http://www.tannerhelland.com/wp-content/uploads/2010/03/Mandelbrot_VB6_4.png" alt="" width="602" height="602" /></a>
</div>
<div class="captionfull">
<a  rel="attachment wp-att-1500" href="http://www.tannerhelland.com/1494/mandelbrot-vb6/mandelbrot_vb6_5/"><img class="aligncenter size-full wp-image-1500" title="Mandelbrot_VB6_5" src="http://www.tannerhelland.com/wp-content/uploads/2010/03/Mandelbrot_VB6_5.png" alt="" width="603" height="602" /></a>
</div>
<div class="captionfull">
<a rel="attachment wp-att-1501" href="http://www.tannerhelland.com/1494/mandelbrot-vb6/mandelbrot_vb6_6/"><img class="aligncenter size-full wp-image-1501" title="Mandelbrot_VB6_6" src="http://www.tannerhelland.com/wp-content/uploads/2010/03/Mandelbrot_VB6_6.png" alt="" width="602" height="603" />
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.tannerhelland.com/1494/mandelbrot-vb6/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Artificial Life Simulator (in VB6)</title>
		<link>http://www.tannerhelland.com/1399/artificial-life-simulator-vb6/</link>
		<comments>http://www.tannerhelland.com/1399/artificial-life-simulator-vb6/#comments</comments>
		<pubDate>Tue, 22 Dec 2009 06:09:11 +0000</pubDate>
		<dc:creator>Tanner</dc:creator>
				<category><![CDATA[Bioinformatics]]></category>
		<category><![CDATA[Game Code]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[AI]]></category>

		<guid isPermaLink="false">http://www.tannerhelland.com/?p=1399</guid>
		<description><![CDATA[Here you have it: the largest, most complex programming project now available on tannerhelland.com. Originally a final project for a university bioinformatics course, this artificial life simulator has now been completely retooled as a full-blown lesson in evolution and population genetics.  As with most artificial life simulators, a set of simple artificial creatures compete for limited resources.  Each creature has a strand of pseudo-DNA that determines three basic attributes: size, speed, and range (how far it can see)...]]></description>
			<content:encoded><![CDATA[<div class="captionfull"><a  rel="attachment wp-att-1398" href="http://www.tannerhelland.com/1399/artificial-life-simulator-vb6/artificial_life/"><img class="aligncenter size-large wp-image-1398" title="Artificial_Life" src="http://www.tannerhelland.com/wp-content/uploads/2009/12/Artificial_Life-600x467.png" alt="This is what the Artificial Life Simulator looks like in action" width="600" height="467" /></a></div>
<p><strong>The Short Description:</strong></p>
<p>Here you have it: the largest, most complex programming project now available on tannerhelland.com.  Originally a final project for a university bioinformatics course, my artificial life simulator has now been completely retooled as a full-blown lesson in evolution and population genetics.</p>
<p>As with most artificial life simulators, a set of simple artificial creatures compete for limited resources.   Each creature has a strand of pseudo-DNA that determines three basic attributes: size, speed, and range (how far it can see).  When the little critters reproduce (asexually&#8230; unfortunately), mutations may occur.  Over time, this can lead to remarkable changes in gene frequency throughout the population.  Typically the creatures with a balance of speed and range tend to win out over bigger, slower creatures and smaller, faster ones.</p>
<p>The code is well-optimized, so it should run decently on any hardware.   As a bonus, the simulator can be surprisingly addicting &#8211; my longest simulation to date ran for over 500,000 cycles before all the creatures died.   For further analysis of a particular simulation run, all data can be saved to a tab-delimited text file compatible with any major spreadsheet software.</p>
<p><strong>The Long Description:</strong></p>
<p>As you can imagine, a project of this magnitude warrants a fair amount of documentation.  I am currently working on a <em>&#8220;how to use this software to teach evolution and population genetics&#8221;</em> tutorial that educators &#8211; or anyone interested in biology &#8211; can read to see how things like genetic drift, population equilibrium, the &#8220;bottleneck&#8221; effect, and other aspects of a small, closed population work.</p>
<p>Unfortunately, a document like that takes some time to create&#8230; so rather than holding off until I&#8217;ve finished it, I&#8217;ve decided to upload the project for people to start playing with.  If you have any comments or questions, let me know and I&#8217;ll see if I can&#8217;t work answers into the final version of the tutorial.</p>
<p>(If you&#8217;d like to be notified when the documentation is finished, please let me know via the <a  href="http://www.tannerhelland.com/contact/" target="_blank">contact form</a>.  I plan on sending out an email once all updates have been posted.)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tannerhelland.com/1399/artificial-life-simulator-vb6/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hidden Markov Models, the Viterbi Algorithm, and CpG Islands (in VB6)</title>
		<link>http://www.tannerhelland.com/1187/hidden-markov-models-viterbi-algorithm-cpg-islands-in-vb6/</link>
		<comments>http://www.tannerhelland.com/1187/hidden-markov-models-viterbi-algorithm-cpg-islands-in-vb6/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 02:08:09 +0000</pubDate>
		<dc:creator>Tanner</dc:creator>
				<category><![CDATA[Bioinformatics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Hidden Markov models]]></category>
		<category><![CDATA[HMM]]></category>
		<category><![CDATA[science is cool]]></category>
		<category><![CDATA[Viterbi algorithm]]></category>

		<guid isPermaLink="false">http://www.tannerhelland.com/?p=1187</guid>
		<description><![CDATA[Today's project is something new to this site - bioinformatics code!  I feel a tad ridiculous that it's taken me so many years to post code related to my field, but hey - better late than never. Read on to discover the awesomeness of Hidden Markov models, the Viterbi algorithm (also known as Viterbi paths), CpG islands, and how these all work together to help scientists locate genes.]]></description>
			<content:encoded><![CDATA[<div id="attachment_1188" class="wp-caption aligncenter" style="width: 480px"><a  href="http://commons.wikimedia.org/wiki/File:3D-SIM-4_Anaphase_3_color.jpg"><img class="size-full wp-image-1188" title="3D-SIM-4_Anaphase_3_color" src="http://www.tannerhelland.com/wp-content/uploads/2009/08/3D-SIM-4_Anaphase_3_color.jpg" alt="Anaphase, courtesy of Lothar Schermelleh" width="470" height="356" /></a><p class="wp-caption-text">Anaphase, courtesy of Lothar Schermelleh</p></div>
<p>Today&#8217;s project is something new to this site &#8211; some bioinformatics code!  I feel a tad ridiculous that it&#8217;s taken me so many years to post code related to my field, but hey &#8211; better late than never.  (That seems to be a <a  href="http://www.tannerhelland.com/philosophy/affirmations-skepticism/">recurring</a> <a  href="http://www.tannerhelland.com/site-news/sharing-is-good/">theme</a> around here&#8230;)</p>
<p>First, a primer.  If you don&#8217;t know what the title of this article refers to, here are some Wikipedia links to get you started:</p>
<p><a  href="http://en.wikipedia.org/wiki/Hidden_Markov_model" target="_blank">Hidden Markov models (including some examples in Python)</a></p>
<p><a  href="http://en.wikipedia.org/wiki/Viterbi_path" target="_blank">Viterbi algorithm / Viterbi paths (including even more Python examples)</a></p>
<p><a  href="http://en.wikipedia.org/wiki/CpG_islands" target="_blank">CpG islands</a></p>
<p>As a bonus, I&#8217;m including sections from my original write-up on this program (it began as a university project) in hopes that they&#8217;ll shed some light on how the code works and what its potential usefulness is.</p>
<p>The algorithm implementations are quite fast, and the visual feedback is an excellent addition (IMO).  Full source code and a sample executable are provided, as well as a FASTA file with data from chromosome #1 in the human genome (bases 6000-12000, I believe).</p>
<p><em>(FYI, my original lab assignment link is here: <a  href="http://dna.cs.byu.edu/bio465/Labs/hmm.shtml" target="_blank">http://dna.cs.byu.edu/bio465/Labs/hmm.shtml</a>.  It contains quite a bit of helpful information and links if you&#8217;re looking to write your own HMM implementation.)</em></p>
<p><strong>INTRODUCTION</strong></p>
<p>CpG islands are regions of DNA characterized by a large number of adjacent cytosine and guanine nucletoides linked by phosphodiester bonds. Additionally, CpG islands appear in some 70% of promoters of human genes (40% of mammalian genes). Unlike CpG sites in the coding region of a gene, in most instances the CpG sites in CpG islands are unmethylated if genes are expressed. This observation led to the speculation that methylation of CpG sites in the promoter of a gene may inhibit the expression of a gene. (Wikipedia, retrieved Feb 2007)</p>
<p>In this project, I was particularly concerned with generating an accurate Hidden Markov model to define the relationship between normal states (B) and island states (I) within a region of the human chromosome. Such an implementation is useful for gene finding, as CpG islands tend to appear near the promoters of important mammalian genes.  The automation of this process is critical because such islands are impossible to locate by simply looking at a strand of DNA (they may cover several hundred bases and their C/G content may be only slightly higher than expected values).</p>
<p><strong>PROCEDURE</strong></p>
<p>I opted to code this project in the Microsoft Visual Basic 6.0 programming language.  I believe this implementation is highly appropriate, as I can quickly generate both graphs for visualization and a simple, easy-to-modify GUI (since finding CpG islands can require a lot of trial-and-error using different parameters, and this is not conducive to a command-line program).  VB6 is excellent for quickly assembling GUIs, and for algorithms of this nature its speed is comparable to that of a raw C++ implementation.  (BTW, if you are a Linux user please note that this project works flawlessly under Wine 1.1.27, and likely earlier versions as well.)</p>
<p>I will refer to the following image as I walk through my implementation of a HMM.</p>
<div class="captionfull"><img class="aligncenter size-large wp-image-1189" title="HMM_screenshot" src="http://www.tannerhelland.com/wp-content/uploads/2009/08/HMM_screenshot-600x401.png" alt="HMM_screenshot" width="600" height="401" /></div>
<p><span style="text-decoration: underline;">Step 1: Loading a FASTA file</span><br />
This routine isn’t of much interest, except to mention a programming quirk particular to VB6. A, C, G, and T entries from the FASTA file are reassigned into a byte array as the numbers 0, 1, 2, and 3.  In VB6, number comparison and processing is generally faster than string comparison and processing. (To any VB experts reading this &#8211; please note that I am aware of mechanisms for overcoming this, but the fact of the matter is that I prefer working with byte arrays. :)</p>
<p><span style="text-decoration: underline;">Step 2: HMM Parameters</span><br />
As per the lab specifications, the user can change 14 HMM-related parameters. Additionally, I have chosen to add an option to let the program estimate the eight state probabilities.  This is a trivial operation, but it seems to markedly increase the accuracy of the algorithm. The estimation of A, C, G and T&#8217;s being emitted in a B state is computed by the percentage of occurrences of each of these entries in the original FASTA data.  I predict that given the low percentage of I states in a length of DNA, this method of estimating emission probabilities is likely quite accurate.  Once those categories have been determined, the I state probabilities are computed by doubling the C and G probabilities and halving the A and T probabilities.</p>
<p><span style="text-decoration: underline;">Step 3: The HMM and Viterbi algorithms</span><br />
This step begins by moving all HMM parameters into look-up tables. The logs of these values are pre-calculated, allowing us to add them (instead of multiplying) for future HMM calculations. </p>
<p>Next, all HMM probabilities are calculated and stored.</p>
<p>This is followed by a 2nd loop backward through the data while calculating all data necessary for the Viterbi algorithm. (Note: this is not necessarily the most efficient way to do this, but the speed difference is negligible for sequences less than 100,000 bases long.) </p>
<p>After all Viterbi data has been pre-calculated, the traceback part of the Viterbi algorithm becomes extremely fast.  (Another note: execution speed of this chunk of code is slightly reduced because I translate the states into a string and display that string in the textbox in the upper-right of the program window. This is mainly for convenience and/or to satisfy my curiosity.)</p>
<p><span style="text-decoration: underline;">Step 4: The Sliding Window</span><br />
This step is one where I felt a proper GUI was essential.  I have chosen to display two graphs; the top graph displays raw counts of C and G occurrences as compared to the expected value (where 0.5 is used as the expected ratio).  The bottom graph displays the ratio of I and B states, and it is this data that is used to recommend the location of any CpG islands.</p>
<p>A noteworthy shortcoming of this implementation is that it is designed to only find the <em>most </em>probable CpG island (instead of multiple islands). In a more formal implementation, returning any/all potential CpG island locations would be more useful.</p>
<p>(And for the record, this step is my favorite part of the program.  I find it to be well-implemented and surprisingly graphically pleasing for a bioinformatics tool. :)</p>
<p><strong>RESULTS</strong><br />
By my estimation, the program&#8217;s most accurate CpG prediction for this FASTA file is bases 2018-2045 (which corresponds to bases 6018-6045 in the original data, I believe). If you run the program yourself, you will find that most of its estimates fall around this range.  Adjusting the sliding window doesn&#8217;t have tremendous effect on the estimates, although larger windows will result in larger CpG island predictions (not surprising).  The percentage of I states varies dramatically; certain parameters result in levels as high as 30-40% while others are less than 5%.  For my best estimate (above), the percentage of I states was 22%.</p>
<p>Finally, code execution is swift &#8211; typically a matter of seconds &#8211; and if the text display in the top-right is disabled the program runs more-or-less instantaneously on modern hardware.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tannerhelland.com/1187/hidden-markov-models-viterbi-algorithm-cpg-islands-in-vb6/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sepia / “Antique” Image Effect (in VB6)</title>
		<link>http://www.tannerhelland.com/1138/sepia-antique-effect-vb6/</link>
		<comments>http://www.tannerhelland.com/1138/sepia-antique-effect-vb6/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 02:23:31 +0000</pubDate>
		<dc:creator>Tanner</dc:creator>
				<category><![CDATA[Graphics Code]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[graphics programming]]></category>
		<category><![CDATA[Photoshop]]></category>

		<guid isPermaLink="false">http://www.tannerhelland.com/?p=1138</guid>
		<description><![CDATA[I'm guessing you've seen this style of image before - a sort of pseudo-antique filter than can make any image look like it was taken with a very old camera.  There are many ways to programmatically generate images like this, and in this article I've put together one that does more than just make the image look "brown."  This filter involves several steps (fading, multiplicative brightness, and gamma correction, among others) and results in a conversion that not only adds a sepia coloring, but also gives an image a histogram more in keeping with older photos.]]></description>
			<content:encoded><![CDATA[<div class="captionfull">
<div id="attachment_1141" class="wp-caption aligncenter" style="width: 480px"><img class="size-full wp-image-1141" title="Sepia_Big_Bang_Theory" src="http://www.tannerhelland.com/wp-content/uploads/2009/08/Sepia_Big_Bang_Theory.jpg" alt="&quot;Antiquified&quot; version of a BBT promo photo" width="470" height="353" /><p class="wp-caption-text">&quot;Antiquified&quot; version of a BBT promo photo</p></div>
</div>
<p>I&#8217;m guessing you&#8217;ve seen this style of image before &#8211; a sort of pseudo-antique filter than can make any photo look like it was taken with a very old camera (or even a <a  href="http://en.wikipedia.org/wiki/Daguerreotype" target="_blank">daguerreotype</a> &#8211; how&#8217;s that for a cool word?).  There are many ways to programmatically generate images like this, and in this article I&#8217;ve put together one that does more than just make the image look &#8220;brown.&#8221;  This filter involves several steps (fading, multiplicative brightness, and gamma correction, among others) and results in a conversion that not only adds a sepia coloring, but also gives an image a histogram more in keeping with older photos.</p>
<p>As with all graphics code on this site, the algorithm is fast enough to be applied in real-time.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tannerhelland.com/1138/sepia-antique-effect-vb6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nature-Inspired Image Filters (in VB6)</title>
		<link>http://www.tannerhelland.com/1118/nature-inspired-image-effects-vb6/</link>
		<comments>http://www.tannerhelland.com/1118/nature-inspired-image-effects-vb6/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 00:22:21 +0000</pubDate>
		<dc:creator>Tanner</dc:creator>
				<category><![CDATA[Graphics Code]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[graphics programming]]></category>
		<category><![CDATA[Photoshop]]></category>

		<guid isPermaLink="false">http://www.tannerhelland.com/?p=1118</guid>
		<description><![CDATA[Today's article brings a collection of random image effects that can be quickly (and programmatically) generated. In an attempt to give the project some coherency, I've named each effect after something "nature-themed" so as to help distinguish them.  As always, full source code and a sample .exe is provided...]]></description>
			<content:encoded><![CDATA[<p>Today&#8217;s article brings a collection of random image effects that can be quickly (and programmatically) generated.  In an attempt to give the project some coherency, I&#8217;ve named each effect after something &#8220;nature-themed&#8221; so as to help distinguish them.</p>
<p>Below, you can see how each filter looks on a promotional image from <a  href="http://en.wikipedia.org/wiki/Final_Fantasy_Versus_XIII" target="_blank"><em>Final Fantasy Versus XIII</em></a>.</p>
<p>Original:</p>
<div class="captionfull">
<div id="attachment_1115" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-1115" title="FFVS13" src="http://www.tannerhelland.com/wp-content/uploads/2009/07/FFVS13-600x337.jpg" alt="Final Fantasy Versus XIII" width="600" height="337" /><p class="wp-caption-text">Final Fantasy Versus XIII</p></div>
</div>
<p>Atmosphere:</p>
<div class="captionfull">
<div id="attachment_1116" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-1116" title="FFVS13_Atmosphere" src="http://www.tannerhelland.com/wp-content/uploads/2009/07/FFVS13_Atmosphere-600x337.jpg" alt="Final Fantasy Versus XIII - Atmosphere Effect" width="600" height="337" /><p class="wp-caption-text">Final Fantasy Versus XIII - Atmosphere Effect</p></div>
</div>
<p>Burn:</p>
<div class="captionfull">
<div id="attachment_1117" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-1117" title="FFVS13_Burn" src="http://www.tannerhelland.com/wp-content/uploads/2009/07/FFVS13_Burn-600x337.jpg" alt="Final Fantasy Versus XIII - Burn Effect" width="600" height="337" /><p class="wp-caption-text">Final Fantasy Versus XIII - Burn Effect</p></div>
</div>
<p>Fog:</p>
<div class="captionfull">
<div id="attachment_1119" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-1119" title="FFVS13_Fog" src="http://www.tannerhelland.com/wp-content/uploads/2009/07/FFVS13_Fog-600x337.jpg" alt="Final Fantasy Versus XIII - Fog Effect" width="600" height="337" /><p class="wp-caption-text">Final Fantasy Versus XIII - Fog Effect</p></div>
</div>
<p>Freeze:</p>
<div class="captionfull">
<div id="attachment_1120" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-1120" title="FFVS13_Freeze" src="http://www.tannerhelland.com/wp-content/uploads/2009/07/FFVS13_Freeze-600x337.jpg" alt="Final Fantasy Versus XIII - Freeze Effect" width="600" height="337" /><p class="wp-caption-text">Final Fantasy Versus XIII - Freeze Effect</p></div>
</div>
<p>Lava:</p>
<div class="captionfull">
<div id="attachment_1121" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-1121" title="FFVS13_Lava" src="http://www.tannerhelland.com/wp-content/uploads/2009/07/FFVS13_Lava-600x337.jpg" alt="Final Fantasy Versus XIII - Lava Effect" width="600" height="337" /><p class="wp-caption-text">Final Fantasy Versus XIII - Lava Effect</p></div>
</div>
<p>Ocean:</p>
<div class="captionfull">
<div id="attachment_1122" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-1122" title="FFVS13_Ocean" src="http://www.tannerhelland.com/wp-content/uploads/2009/07/FFVS13_Ocean-600x337.jpg" alt="Final Fantasy Versus XIII - Ocean Effect" width="600" height="337" /><p class="wp-caption-text">Final Fantasy Versus XIII - Ocean Effect</p></div>
</div>
<p>Rainbow:</p>
<div class="captionfull">
<div id="attachment_1123" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-1123" title="FFVS13_Rainbow" src="http://www.tannerhelland.com/wp-content/uploads/2009/07/FFVS13_Rainbow-600x337.jpg" alt="Final Fantasy Versus XIII - Rainbow Effect" width="600" height="337" /><p class="wp-caption-text">Final Fantasy Versus XIII - Rainbow Effect</p></div>
</div>
<p>Metal:</p>
<div class="captionfull">
<div id="attachment_1124" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-1124" title="FFVS13_Metal" src="http://www.tannerhelland.com/wp-content/uploads/2009/07/FFVS13_Steel-600x337.jpg" alt="Final Fantasy Versus XIII - Metal Effect" width="600" height="337" /><p class="wp-caption-text">Final Fantasy Versus XIII - Metal Effect</p></div>
</div>
<p>Underwater:</p>
<div class="captionfull">
<div id="attachment_1125" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-1125" title="FFVS13_Water" src="http://www.tannerhelland.com/wp-content/uploads/2009/07/FFVS13_Water-600x337.jpg" alt="Final Fantasy Versus XIII - Underwater Effect" width="600" height="337" /><p class="wp-caption-text">Final Fantasy Versus XIII - Underwater Effect</p></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.tannerhelland.com/1118/nature-inspired-image-effects-vb6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom Image Filter Engine (in VB6)</title>
		<link>http://www.tannerhelland.com/982/custom-image-filters-vb6/</link>
		<comments>http://www.tannerhelland.com/982/custom-image-filters-vb6/#comments</comments>
		<pubDate>Tue, 05 May 2009 06:00:48 +0000</pubDate>
		<dc:creator>Tanner</dc:creator>
				<category><![CDATA[Graphics Code]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[graphics programming]]></category>
		<category><![CDATA[Photoshop]]></category>
		<category><![CDATA[Photoshop Code]]></category>
		<category><![CDATA[photoshop programming]]></category>

		<guid isPermaLink="false">http://www.tannerhelland.com/?p=982</guid>
		<description><![CDATA[The ability to create custom filters is a mainstay of any quality graphics application.  A robust matrix-based filter engine can be used to create tens - even hundreds - of unique image effects by simply manipulating the matrices that get passed into the engine.  In this project, I've provided a 5x5 custom filter engine with support for both scaling and biasing.  This is identical to the custom filter engine provided by Photoshop, and mine is even slightly faster (at least for the screen-sized images I've been testing)...]]></description>
			<content:encoded><![CDATA[<p>The ability to create custom filters is a mainstay of any quality graphics application.  A robust matrix-based filter engine can generate hundreds of unique effects by simply adjusting the matrices that get passed into the engine.</p>
<p>In this project, I&#8217;ve provided a 5&#215;5 custom filter engine with support for scaling/weighting and biasing/offsetting.   This is identical to the custom filter engine provided by Photoshop, and mine is even slightly faster (at least for the screen-sized images I&#8217;ve been testing).</p>
<p>Besides being fast, the engine is also smart.   It is clever enough to estimate edge pixels correctly &#8211; even for scaled/weighted filters &#8211; and it will automatically validate all input values to make sure they&#8217;re appropriate.</p>
<p>Finally, I&#8217;ve included 7 sample filters for you to play with, including blur, sharpen, emboss, engrave, grease, unfocus, and vibrate. Below, you can see how each filter looks on a promotional image from <a  href="http://abc.go.com/primetime/castle/index?pn=index" target="_blank"><em>Castle</em></a>, an excellent new NYPD dramedy on ABC.</p>
<p>Original:</p>
<div class="captionfull"><img class="aligncenter size-full wp-image-974" title="castle" src="http://www.tannerhelland.com/wp-content/uploads/2009/05/castle.jpg" alt="castle" width="400" height="300" /></div>
<p>Blur:</p>
<div class="captionfull"><img class="aligncenter size-full wp-image-975" title="castle_blur" src="http://www.tannerhelland.com/wp-content/uploads/2009/05/castle_blur.jpg" alt="castle_blur" width="400" height="300" /></div>
<p>Sharpen:</p>
<div class="captionfull"><img class="aligncenter size-full wp-image-976" title="castle_sharpen" src="http://www.tannerhelland.com/wp-content/uploads/2009/05/castle_sharpen.jpg" alt="castle_sharpen" width="400" height="300" /></div>
<p>Emboss:</p>
<div class="captionfull"><img class="aligncenter size-full wp-image-977" title="castle_emboss" src="http://www.tannerhelland.com/wp-content/uploads/2009/05/castle_emboss.jpg" alt="castle_emboss" width="400" height="300" /></div>
<p>Engrave:</p>
<div class="captionfull"><img class="aligncenter size-full wp-image-978" title="castle_engrave" src="http://www.tannerhelland.com/wp-content/uploads/2009/05/castle_engrave.jpg" alt="castle_engrave" width="400" height="300" /></div>
<p>Grease:</p>
<div class="captionfull"><img class="aligncenter size-full wp-image-979" title="castle_grease" src="http://www.tannerhelland.com/wp-content/uploads/2009/05/castle_grease.jpg" alt="castle_grease" width="400" height="300" /></div>
<p>Unfocus:</p>
<div class="captionfull"><img class="aligncenter size-full wp-image-980" title="castle_unfocus" src="http://www.tannerhelland.com/wp-content/uploads/2009/05/castle_unfocus.jpg" alt="castle_unfocus" width="400" height="300" /></div>
<p>Vibrate:</p>
<div class="captionfull"><img class="aligncenter size-full wp-image-981" title="castle_vibrate" src="http://www.tannerhelland.com/wp-content/uploads/2009/05/castle_vibrate.jpg" alt="castle_vibrate" width="400" height="300" /></div>
]]></content:encoded>
			<wfw:commentRss>http://www.tannerhelland.com/982/custom-image-filters-vb6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Edge Detection (in VB6)</title>
		<link>http://www.tannerhelland.com/952/edge-detection-vb6/</link>
		<comments>http://www.tannerhelland.com/952/edge-detection-vb6/#comments</comments>
		<pubDate>Sat, 02 May 2009 04:09:13 +0000</pubDate>
		<dc:creator>Tanner</dc:creator>
				<category><![CDATA[Graphics Code]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[graphics programming]]></category>
		<category><![CDATA[Photoshop]]></category>

		<guid isPermaLink="false">http://www.tannerhelland.com/?p=952</guid>
		<description><![CDATA[Edge detection (also called "boundary detection") is a fundamental problem in image processing.  The ability to accurately detect visible "edges" in an image has many applications - from missile targeting to OCR to cool Photoshop effects.  In this project, I've compiled 6 well-known edge detection algorithms (along with two of my own for fun).  Full VB6 source code is provided, as well as an .exe for those just interested in the effects alone...]]></description>
			<content:encoded><![CDATA[<p>Edge detection (also called &#8220;boundary detection&#8221;) is a fundamental problem in image processing.  The ability to accurately detect visible &#8220;edges&#8221; in an image has many applications &#8211; ranging from missile targeting to OCR to cool Photoshop effects.  In this project I&#8217;ve compiled 6 well-known edge detection algorithms (along with two of my own for fun).  Full VB6 source code is provided, along with an .exe for those interested in just the effect.</p>
<p>For those who have never used edge detection algorithms before, here&#8217;s an idea of the output:</p>
<p>Original image:</p>
<p>
<div class="captionfull"><img class="aligncenter size-full wp-image-953" title="Lost_TV" src="http://www.tannerhelland.com/wp-content/uploads/2009/05/wa_lost-cast_02.jpg" alt="Lost_TV" width="400" height="300" /></div>
</p>
<p>Prewitt method (horizontal):</p>
<p>
<div class="captionfull"><img class="aligncenter size-full wp-image-954" title="lost_1" src="http://www.tannerhelland.com/wp-content/uploads/2009/05/lost_1.jpg" alt="lost_1" width="400" height="300" /></div>
</p>
<p>Prewitt method (vertical):</p>
<p>
<div class="captionfull"><img class="aligncenter size-full wp-image-955" title="lost_2" src="http://www.tannerhelland.com/wp-content/uploads/2009/05/lost_2.jpg" alt="lost_2" width="400" height="300" /></div>
</p>
<p>Sobel method (horizontal):</p>
<p>
<div class="captionfull"><img class="aligncenter size-full wp-image-956" title="lost_3" src="http://www.tannerhelland.com/wp-content/uploads/2009/05/lost_3.jpg" alt="lost_3" width="400" height="300" /></div>
</p>
<p>Sobel method (vertical):</p>
<p>
<div class="captionfull"><img class="aligncenter size-full wp-image-957" title="lost_4" src="http://www.tannerhelland.com/wp-content/uploads/2009/05/lost_4.jpg" alt="lost_4" width="400" height="300" /></div>
</p>
<p>Laplacian method:</p>
<p>
<div class="captionfull"><img class="aligncenter size-full wp-image-958" title="lost_5" src="http://www.tannerhelland.com/wp-content/uploads/2009/05/lost_5.jpg" alt="lost_5" width="400" height="300" /></div>
</p>
<p>Hilite method:</p>
<p>
<div class="captionfull"><img class="aligncenter size-full wp-image-959" title="lost_6" src="http://www.tannerhelland.com/wp-content/uploads/2009/05/lost_6.jpg" alt="lost_6" width="400" height="300" /></div>
</p>
<p>Tanner&#8217;s method 1:</p>
<p>
<div class="captionfull"><img class="aligncenter size-full wp-image-960" title="lost_7" src="http://www.tannerhelland.com/wp-content/uploads/2009/05/lost_7.jpg" alt="lost_7" width="400" height="300" /></div>
</p>
<p>Tanner&#8217;s method 2:</p>
<p>
<div class="captionfull"><img class="aligncenter size-full wp-image-961" title="lost_8" src="http://www.tannerhelland.com/wp-content/uploads/2009/05/lost_8.jpg" alt="lost_8" width="400" height="300" /></div></p>
]]></content:encoded>
			<wfw:commentRss>http://www.tannerhelland.com/952/edge-detection-vb6/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Advanced Image Histograms in VB6 – Stretching and Equalizing</title>
		<link>http://www.tannerhelland.com/810/vb6-image-histograms-2/</link>
		<comments>http://www.tannerhelland.com/810/vb6-image-histograms-2/#comments</comments>
		<pubDate>Wed, 25 Mar 2009 14:00:57 +0000</pubDate>
		<dc:creator>Tanner</dc:creator>
				<category><![CDATA[Graphics Code]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[advanced graphics]]></category>
		<category><![CDATA[histograms]]></category>
		<category><![CDATA[VB]]></category>

		<guid isPermaLink="false">http://www.tannerhelland.com/?p=810</guid>
		<description><![CDATA[As promised, here is the second half of my histogram code project.  In this project, I'll show you how to stretch a histogram, equalize individual channels, and - most useful of all - equalize an image's overall luminance.  Cool, eh?]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><em>This is the 2nd half of a two-part project.  Part 1 is available <a  href="http://www.tannerhelland.com/vb6/vb6-image-histograms-1/">here</a>.</em></p>
<p>As promised, here is the second half of my histogram code project.  In this project, I&#8217;ll show you how to stretch a histogram, equalize individual channels, and &#8211; most useful of all &#8211; equalize an image&#8217;s overall luminance.  Cool, eh?</p>
<p><strong>Stretching a Histogram</strong></p>
<p>The most straightforward of these functions is stretching a histogram.  The idea is this: many images stretch from pretty-dark colors to pretty-light colors, but they don&#8217;t take advantage of the full luminance spectrum by stretching all the way from pure black to pure light.  (For example, a &#8220;washed-out&#8221; image typically fails to utilize the entire luminance spectrum.)  To help fix an image like this, it is necessary to adjust the image&#8217;s colors to better span all possible brightness values.</p>
<p>Stretching does this by finding the darkest and lightest values in an image, then performing an automatic conversion between that color range (max &#8211; min) and the ideal color range (pure white &#8211; pure black).</p>
<p>As an example, here is an image that doesn&#8217;t span the full brightness spectrum:</p>
<div class="captionfull"><img class="aligncenter size-large wp-image-812" title="Normal Clouds" src="http://www.tannerhelland.com/wp-content/uploads/2009/03/cloudsnormal-600x449.jpg" alt="Normal Clouds" width="600" height="449" /></div>
<p>Notice how the top half of the histogram is empty?  The brightest pixels in this image are only a mid-level gray.</p>
<p>Here is the same image after running a stretch histogram algorithm:</p>
<div class="captionfull"><img class="aligncenter size-large wp-image-813" title="Stretched Clouds" src="http://www.tannerhelland.com/wp-content/uploads/2009/03/cloudsstretched-600x449.jpg" alt="Stretched Clouds" width="600" height="449" /></div>
<p>Notice how the histogram now stretches all the way to pure white?  Admittedly, this picture is not the best example of how stretching can be useful &#8211; but it&#8217;s a good demonstration of what stretching does.</p>
<p>Stretching is a fast and simple function, but its useful is limited.  Take the following image, for example:</p>
<div class="captionfull"><img class="aligncenter size-large wp-image-814" title="Normal Tiger" src="http://www.tannerhelland.com/wp-content/uploads/2009/03/normaltiger-600x449.jpg" alt="Normal Tiger" width="600" height="449" /></div>
<p>The colors in this tiger picture stretch all the way from pure black to pure white, but they seem to be more heavily concentrated toward the dark end of the luminance spectrum.  To really fix this picture, we need to redistribute its colors across the spectrum in a more equal way.</p>
<p>Enter equalization.</p>
<p><strong>Equalizing a Histogram</strong></p>
<p>Equalizing is a more complex and time-consuming function than stretching, but it is able to fix problems outside the reach of stretching alone.</p>
<p>Here is the tiger image post-equalization:</p>
<div class="captionfull"><img class="aligncenter size-large wp-image-815" title="Equalized Tiger" src="http://www.tannerhelland.com/wp-content/uploads/2009/03/equalizedtiger-600x449.jpg" alt="Equalized Tiger" width="600" height="449" /></div>
<p>See how much more balanced the histogram has become?  As another example, here is the cloud picture from above after both stretching and equalizing:</p>
<div class="captionfull"><img class="aligncenter size-large wp-image-816" title="Stretched and Equalized Clouds" src="http://www.tannerhelland.com/wp-content/uploads/2009/03/cloudsstretchequalize-600x449.jpg" alt="Stretched and Equalized Clouds" width="600" height="449" /></div>
<p>Equalizing has brought out a bunch of details that weren&#8217;t apparent in the original image.</p>
<p>Rather than going through the gory details of how histogram equalizing works, I&#8217;m going to refer you to the excellent Wikipedia article on the subject:</p>
<p><a  href="http://en.wikipedia.org/wiki/Histogram_equalization" target="_blank">http://en.wikipedia.org/wiki/Histogram_equalization</a></p>
<p>Also, I&#8217;d like to quote one very applicable comment from the above article (emphasis added by me):</p>
<blockquote><p>The above describes histogram equalization on a greyscale image. However, it can also be used on color images by applying the same method separately to the Red, Green and Blue components of the RGB color values of the image. Still, <strong>it should be noted that applying the same method on the Red, Green, and Blue components of an RGB image may yield dramatic changes in the image&#8217;s color balance</strong> since the relative distributions of the color channels change as a result of applying the algorithm. <strong>However, if the image is first converted to another color space, Lab color space, or HSL/HSV color space in particular, then the algorithm can be applied to the luminance or value channel without resulting in changes to the hue and saturation of the image</strong>.</p></blockquote>
<p>Because of this, I have supplied two equalizing algorithms in this project &#8211; one that equalizes any combination of color channels, and another that equalizes only luminance.  The luminance method provides the code for converting between RGB and HSL color spaces&#8230;and that code is very complex.  It&#8217;s probably worth your while to take that code on faith for now, and maybe at a future date I&#8217;ll discuss color space transformations in more detail.</p>
<p><strong>Get the Code!</strong></p>
<p>But enough chat!  Here&#8217;s the link for the code:</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tannerhelland.com/810/vb6-image-histograms-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/


Served from: www.tannerhelland.com @ 2010-09-03 08:46:50 -->