<?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>Kerry D. Wong</title>
	<atom:link href="http://www.kerrywong.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kerrywong.com</link>
	<description></description>
	<lastBuildDate>Fri, 05 Feb 2010 14:20:34 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>An Isolated MOSFET Serial Port Relay Controller</title>
		<link>http://www.kerrywong.com/2010/02/04/an-isolated-mosfet-serial-port-relay-controller/</link>
		<comments>http://www.kerrywong.com/2010/02/04/an-isolated-mosfet-serial-port-relay-controller/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 01:48:26 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[MOSFET]]></category>
		<category><![CDATA[RS232]]></category>
		<category><![CDATA[Serial Port]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1618</guid>
		<description><![CDATA[Using DTR (data terminal ready) and RTS (request to send) pins of a PC serial port (RS-232) without actually using the serial data pins, we can interface at least two relay devices with a computer.  Windmeadow Labs has an excellent article on how to achieve this using a bipolar transistor (BJT). Here I will [...]]]></description>
			<content:encoded><![CDATA[<p>Using DTR (data terminal ready) and RTS (request to send) pins of a PC serial port (RS-232) without actually using the serial data pins, we can interface at least two relay devices with a computer.  <a href="http://www.windmeadow.com/node/4">Windmeadow Labs has an excellent article</a> on how to achieve this using a <a href="http://en.wikipedia.org/wiki/Bipolar_junction_transistor">bipolar transistor</a> (BJT). Here I will show you a similar relay control circuit built using an <a href="http://en.wikipedia.org/wiki/Opto-isolator">opto-isolator</a> and a <a href="http://en.wikipedia.org/wiki/MOSFET">MOSFET</a>. <span id="more-1618"></span></p>
<p>Here is the circuit diagram:<br />
<div id="attachment_1624" class="wp-caption aligncenter" style="width: 1023px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2010/02/serialportctrl.png"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2010/02/serialportctrl.png" alt="" title="An Isolated MOSFET Serial Port Relay Controller" width="1013" height="498" class="size-full wp-image-1624" /></a><p class="wp-caption-text">An Isolated MOSFET Serial Port Relay Controller</p></div></p>
<p>The benefit of using an opto-isolator is that the rest of the controller circuit is totally isolated from the serial port and thus prevents the port from accidentally being damaged by wrong wiring or current surge due to a failed component. And by replacing the drive circuitry from using a BJT to a MOSFET, the switching capability is improved dramatically, making switching higher current load more reliable and more efficient.</p>
<p>Here is a picture of the finished board:<br />
<div id="attachment_1632" class="wp-caption aligncenter" style="width: 810px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2010/02/serialportctrlboard.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2010/02/serialportctrlboard.jpg" alt="Circuit Board" title="Circuit Board" width="800" height="600" class="size-full wp-image-1632" /></a><p class="wp-caption-text">Circuit Board</p></div></p>
<p>And here is a simple program that toggles the relay on and off at an interval of 0.5 second. </p>
<pre class="brush: cpp;">
#include &lt;sys/ioctl.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;stdlib.h&gt;

#define _SERIAL_PORT &quot;/dev/ttyS0&quot;

int main(int argc, char **argv)
{
        int fd, status = 0, cmd = 0;

        if ((fd = open(_SERIAL_PORT, O_RDWR | O_NDELAY)) &lt; 0)  exit(1);

        while(1) {
                if (cmd) cmd = 0;  else cmd = TIOCM_DTR;

                ioctl(fd, TIOCMSET, &amp;cmd);
                ioctl(fd, TIOCMGET, &amp;status);

                if (status &amp; TIOCM_DTR) puts(&quot;ON&quot;); else puts(&quot;OFF&quot;);
                usleep(500000l);
        }

        close(fd);
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2010/02/04/an-isolated-mosfet-serial-port-relay-controller/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building a Degaussing Coil</title>
		<link>http://www.kerrywong.com/2010/01/18/building-a-degaussing-coil/</link>
		<comments>http://www.kerrywong.com/2010/01/18/building-a-degaussing-coil/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 02:27:50 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Electronics]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1605</guid>
		<description><![CDATA[One of my older CRT TVs does not have a built-in degauss button and after sitting in the corner of the basement for a couple of years, it somehow got magnetized pretty badly. The top two-thirds became totally disclorored with the &#8220;rainbow&#8221; effect.Since the TV works excellent otherwise, I decided to fix the screen magnetization [...]]]></description>
			<content:encoded><![CDATA[<p>One of my older CRT TVs does not have a built-in degauss button and after sitting in the corner of the basement for a couple of years, it somehow got magnetized pretty badly. The top two-thirds became totally disclorored with the &#8220;rainbow&#8221; effect.<span id="more-1605"></span>Since the TV works excellent otherwise, I decided to fix the screen magnetization issue with a <a href="http://en.wikipedia.org/wiki/Degaussing">degaussing</a> coil.</p>
<p>The basic operation principal of a degaussing coil is using a strong and gradual fading magnetic field which has an initial magnetic field many times stronger than the magnetization within the tube (typically in the shadow mask or the supporting frame). To produce such a strong magnetic field, we would need a very strong electromagnet. The simplest way is to find a pre-wound spool of <a href="http://en.wikipedia.org/wiki/Magnet_wire">magnetic wire</a> and connect it to an <a href="http://en.wikipedia.org/wiki/Alternating_current">AC</a> source.</p>
<p>I bought a spool of 28 AWG magnetic wire which is roughly 1000ft. The spool has an inner diameter of roughly 1 inch. To increase the inductance of the coil and make it suitable for use with 110V main power, I added a steel rod as the core (the steel rod came from a used printer which was just a tad thinner than 1 inch). Here&#8217;s a picture of the degaussing coil I built:</p>
<div id="attachment_1609" class="wp-caption aligncenter" style="width: 392px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2010/01/degaussingcoil.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2010/01/degaussingcoil.jpg" alt="Degaussing Coil" title="Degaussing Coil" width="382" height="237" class="size-full wp-image-1609" /></a><p class="wp-caption-text">Degaussing Coil</p></div>
<p>To test the coil, you will have to be careful about the maximum current the magnetic wire coil can carry. Excessive current can cause the coil to melt and possibly burn! If you are unsure about the inductance of the coil, you probably want to use an <a href="http://en.wikipedia.org/wiki/Autotransformer">autotransformer (Variac)</a> and a AC current meter to determine what is the optimal operation voltage for your coil. Or, if you don&#8217;t have such tools, you will at least want to add a 100W light bulb between the coil and the power to limit the maximum current. If the light is dim when you power on the coil, then it indicates that your coil has sufficient inductance to operate using 110V AC power. If the light is very bright, you will have to adjust your design (i.e., adding a core with higher permissibility or add more turns to the winding).</p>
<p>If your construct is the same as mine, then the coil can operate at 110V AC with no overheating issue (current is at roughly 0.35 A when connected).</p>
<div id="attachment_1612" class="wp-caption aligncenter" style="width: 351px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2010/01/degaussingcircuit.png"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2010/01/degaussingcircuit.png" alt="Degaussing Circuit" title="Degaussing Circuit" width="341" height="182" class="size-full wp-image-1612" /></a><p class="wp-caption-text">Degaussing Circuit</p></div>
<p>When degaussing, connect the power and move the coil slowly away from the TV screen to a few feet away in a gradual and circular motion. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2010/01/18/building-a-degaussing-coil/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Simplest MOSFET On/Off Switch</title>
		<link>http://www.kerrywong.com/2010/01/06/the-simplest-mosfet-onoff-switch/</link>
		<comments>http://www.kerrywong.com/2010/01/06/the-simplest-mosfet-onoff-switch/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 23:46:10 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[MOSFET]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1597</guid>
		<description><![CDATA[A touch sensitive on/off switch can be made with a single MOSFET. The following schematics illustrate such a switch using only a power MOSFET (IRFZ22).
In this example, the switching capability is achieved by the dielectric nature of MOSFET&#8217;s gate. Since the gate is insulated from other device regions, the leakage current is relatively small and [...]]]></description>
			<content:encoded><![CDATA[<p>A touch sensitive on/off switch can be made with a single <a href="http://en.wikipedia.org/wiki/MOSFET">MOSFET</a>. The following schematics illustrate such a switch using only a power MOSFET (<a href="http://www.alldatasheet.com/datasheet-pdf/pdf/96663/IRF/IRFZ22.html">IRFZ22</a>).<span id="more-1597"></span></p>
<div id="attachment_1598" class="wp-caption aligncenter" style="width: 507px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2010/01/mosfetswitch.gif"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2010/01/mosfetswitch.gif" alt="Simplest Switch using MOSFET" title="Simplest Switch using MOSFET" width="497" height="319" class="size-full wp-image-1598" /></a><p class="wp-caption-text">Simplest Switch using MOSFET</p></div>
<p>In this example, the switching capability is achieved by the dielectric nature of MOSFET&#8217;s gate. Since the gate is insulated from other device regions, the leakage current is relatively small and thus the capacitor can hold its charge for a relatively long period of time.</p>
<p>When the gate and the positive lead are touched, the relatively small gate capacitor is rapidly charged (dry skin has a resistance of several mega-ohm) and the switch turns on. And when the gate and the ground are touched the gate capacitor quickly discharges and the switch turns off.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2010/01/06/the-simplest-mosfet-onoff-switch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My First Few Days With Chrome for Linux Beta</title>
		<link>http://www.kerrywong.com/2009/12/13/my-first-few-days-with-chrome-for-linux-beta/</link>
		<comments>http://www.kerrywong.com/2009/12/13/my-first-few-days-with-chrome-for-linux-beta/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 02:02:50 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1584</guid>
		<description><![CDATA[When Google Chrome beta for Windows was first released last September, I tested it briefly on a Windows XP box and was quite impressed by its speed and simplistic user interface.
But it would have been too early to tell how the future lies for Google&#8217;s budding browser platform without first seeing it running on other [...]]]></description>
			<content:encoded><![CDATA[<p>When <a href="http://www.google.com/chrome/">Google Chrome</a> beta for Windows was first released last September, I tested it briefly on a Windows XP box and was quite impressed by its speed and simplistic user interface.<span id="more-1584"></span></p>
<p>But it would have been too early to tell how the future lies for Google&#8217;s budding browser platform without first seeing it running on other platforms, particularly on Linux. Although the market share for Linux has been a distant third comparing to Windows and Mac OS (depending on how the market share is calculated the figure goes anywhere between less than 1% to a few percentages), it is a sign of serious commitment when we see the support for Linux finally comes. To be honest, the developer build Chrome for Linux had been around for a while now, but the release of Beta last week was the first official release from Google.</p>
<p>Before I started using it, I wasn&#8217;t keeping my hopes very high. I was prepared to experience some glitches as after all it is still in its early Beta stage and comparing to Firefox, Chrome is only in its infant stage. But the result is much beyond my expectations.</p>
<p>The installation process was pretty much flawless. Google provides both Debian and RPM packages (Chrome 4.0.249.30) and installing on 64bit Ubuntu (9.10) was as simple as any other Ubuntu packages. And upon starting for the first time, it offered to import my favorites from my current Firefox installations. Unfortunately, I had my Firefox sessions open at the time, and it was unable to import the settings. But it was easy enough to manually import all my favorites ones I started using it.</p>
<p>My first impression is that the user interface is very pleasant. It is clean, minimal and almost barren. Like the simple design of its homepage, Google wanted to emphasize on the content and rather the shell. This clean design is also a necessity given Google&#8217;s intension of a Chrome based web-centric OS. Serving as the desktop surface, every square inch of client usable screen real estate counts. This philosophy virtually dictated every aspect of the Chrome browser. When maximized, borders are gone. The top border was shrunk down further&#8211;an other nice touch&#8211;as users do not need to move the window when the browser is maximized. Even the status area is not permanently utilized. It only appears when there is message to display.<br />
All of these efforts add up to give users the maximum screen space.</p>
<p>Another well thought behavior was the slight delay when closing tabs. When you have dozens of open tabs, the tab sizes were adjusted dynamically to accommodate the limited screen width. If you try to close these tabs one by one, it would be annoying if you had to constantly adjust your mouse to find the &#8220;close&#8221; icon of the tab. Google realized this, and designed Chrome such that as long as mouse remains in the tabbing area, the tab sizes do not change. So that closing multiple consecutive windows is a simple matter of multiple mouse clicks, without the need to move or adjust. The tab sizes are only adjusted after a brief delay when the mouse moves out of the &#8220;tabbing&#8221; area (see screen shot below).</p>
<div id="attachment_1589" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/chrome_closingtabs.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/chrome_closingtabs-300x29.jpg" alt="Tab closing behavior" title="Tab closing behavior" width="300" height="29" class="size-medium wp-image-1589" /></a><p class="wp-caption-text">Tab closing behavior</p></div>
<p>Chrome is also a full-fledged web development environment. It has many handy tools (developer->developer tools menu) you would need to inspect/debug your web pages. It even provides a task manager, listing the resources each web page utilizes. Presumably, being an OS rather than a simple browser means that it has to have a task manager of some sort.</p>
<p>Needless to say, page loading in Chrome is generally noticeably faster than that in Firefox. Fast page loading is extremely important for concurrently loading multiple pages (for example, opening a folder of favorites). If a browser is slow, many pages will time out due to the limited rendering capability of the browser. When I loaded a set of a couple dozen or so sites in both Firefox and Chrome, only a couple of sites failed to load properly in Chrome, where as in Firefox as many as ten sites were timed out.</p>
<p>Sites with Flash also worked flawlessly. While this has less to do with Google than Adobe, supporting Flash out-of-box is certainly a nice thought as users generally assume that a web site should just work, regardless of what plug-in is required.</p>
<p>And of course, Chrome is standard compliant. It passes even the most stringent ACID3 browser test. The only gripe I had was the lack of a bookmark menu icon when bookmark bar is not used. In this case, you will have to open the bookmark manager in order to retrieve bookmarked items.</p>
<p>Remember though, this is only a beta browser and it&#8217;s not near its completion by any means. I am sure there would be more pleasant surprises down the pipeline. </p>
<p>Whether or not the Chrome OS lives up to its hype, Chrome as a browser is certainly a serious and credible challenge to Microsoft Internet Explorer and it is here to stay. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/12/13/my-first-few-days-with-chrome-for-linux-beta/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Hall Effect Magnetic Field Polarity Detector</title>
		<link>http://www.kerrywong.com/2009/12/05/a-hall-effect-magnetic-field-polarity-detector/</link>
		<comments>http://www.kerrywong.com/2009/12/05/a-hall-effect-magnetic-field-polarity-detector/#comments</comments>
		<pubDate>Sun, 06 Dec 2009 00:42:00 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Brushless Motor]]></category>
		<category><![CDATA[Hall Effect]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1563</guid>
		<description><![CDATA[Hall effect sensors can be found in many common household gadgets. Most brushless DC motors for instance, like those used in computer cooling fans, contain Hall effect sensors in the driving circuits. I recently replaced one of the cooling fans in my computer and decided to do some experiments with the Hall effect sensor in [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Hall_effect">Hall effect</a> sensors can be found in many common household gadgets. Most <a href="(http://en.wikipedia.org/wiki/Brushless_DC_electric_motor">brushless DC motors</a> for instance, like those used in computer cooling fans, contain Hall effect sensors in the driving circuits.<span id="more-1563"></span> I recently replaced one of the cooling fans in my computer and decided to do some experiments with the Hall effect sensor in that old fan.</p>
<p>After removing the fan rotor you can see the stator and the control circuits. This particular fan is driven by a single chip ATS 277<a href="http://www.datasheetcatalog.org/datasheet2/a/0awqfy74tj776gp8g4esy438whwy.pdf">(the data sheet can be found here)</a>, which is a complementary output Hall effect latch. It turns on and off the alternate side of the poles depending on the rotor&#8217;s position. </p>
<div id="attachment_1565" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/stator.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/stator-300x228.jpg" alt="The stator of a cooling fan" title="The stator of a cooling fan" width="300" height="228" class="size-medium wp-image-1565" /></a><p class="wp-caption-text">The stator of a cooling fan</p></div>
<p>So, using this Hall effect latch IC, we can build a simply electronic circuit that can be used to detect the polarity of a magnet (the magnetic field has to be strong enough to trigger the sensor due to its limited sensitivity).  </p>
<p>Here is the schematics I used to build such a detector:</p>
<div id="attachment_1568" class="wp-caption aligncenter" style="width: 291px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/PolarityDetector.gif"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/PolarityDetector-281x300.gif" alt="Magnetic Polarity Detector Schematic" title="Magnetic Polarity Detector Schematic" width="281" height="300" class="size-medium wp-image-1568" /></a><p class="wp-caption-text">Magnetic Polarity Detector Schematic</p></div>
<p>and here is a picture of the detector after it was built.</p>
<div id="attachment_1571" class="wp-caption aligncenter" style="width: 289px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/detector.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/detector-279x300.jpg" alt="The assembled detector" title="The assembled detector" width="279" height="300" class="size-medium wp-image-1571" /></a><p class="wp-caption-text">The assembled detector</p></div>
<p>When the circuit is powered on, one of the two output will be latched at low and thus the LED connected to that pin will light up: </p>
<div id="attachment_1572" class="wp-caption aligncenter" style="width: 255px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/led1on.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/led1on-245x300.jpg" alt="Activated with one side of the magnet" title="Activated with one side of the magnet" width="245" height="300" class="size-medium wp-image-1572" /></a><p class="wp-caption-text">Activated with one side of the magnet</p></div>
<p>If the Hall sensor detects a strong enough magnetic field, the original pin with the low output will turn high and the other pin will turn low. Thus the blue LED will be off and the red LED will be turned on (see the picture below, note that the red LED is illuminated albeit it is a little dark compared to the blue one).<br />
<div id="attachment_1573" class="wp-caption aligncenter" style="width: 281px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/led2on.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/led2on-271x300.jpg" alt="Activated with the other side of the magnet" title="Activated with the other side of the magnet" width="271" height="300" class="size-medium wp-image-1573" /></a><p class="wp-caption-text">Activated with the other side of the magnet</p></div></p>
<p>By alternating the polarity of the magnetic field (e.g. use the opposite side of the magnet), the LEDs will alternate between blue and red, depending on the polarity used.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/12/05/a-hall-effect-magnetic-field-polarity-detector/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Simple Thread Barrier Implementation</title>
		<link>http://www.kerrywong.com/2009/11/27/a-simple-thread-barrier-implementation/</link>
		<comments>http://www.kerrywong.com/2009/11/27/a-simple-thread-barrier-implementation/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 01:03:38 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Barrier]]></category>
		<category><![CDATA[C Sharp (C#)]]></category>
		<category><![CDATA[Multi-threading]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1540</guid>
		<description><![CDATA[Sometimes a group of concurrently running threads may need to rendezvous at a certain point in time before they can further proceed. This situation commonly arises in areas like event simulation, where the events are synchronized via a clock event (see illustration below):
In the above example, a number of threads start at different times with [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes a group of concurrently running threads may need to rendezvous at a certain point in time before they can further proceed. This situation commonly arises in areas like event simulation, where the events are synchronized via a clock event (see illustration below):<span id="more-1540"></span><br />
<div id="attachment_1541" class="wp-caption aligncenter" style="width: 620px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/11/eventbarrier.gif"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/11/eventbarrier.gif" alt="Event Barrier" title="Event Barrier" width="610" height="176" class="size-full wp-image-1541" /></a><p class="wp-caption-text">Event Barrier</p></div></p>
<p>In the above example, a number of threads start at different times with the arrival of each clock event and wait till all threads finish running before the next clock event arrives.</p>
<p>Such <a href="http://en.wikipedia.org/wiki/Barrier_%28computer_science%29">barrier</a> can be implemented using various techniques with different level of difficulties. <a href="http://www.albahari.com/threading/part3.aspx#_Thread_Pooling">One possible implementation</a> can be found in  <a href="http://www.albahari.com/threading/">Joseph Albahari&#8217;s Threading in C#</a> where a monitor construct is used to wait on a synchronization object in the main thread after the worker threads are queued. </p>
<pre class="brush: csharp;">
    lock (workerLocker)
    {
      while (runningWorkers &gt; 0)
        Monitor.Wait (workerLocker);
    }
</pre>
<p>In each of the worker thread, the number of running workers is decremented when the thread finishes:</p>
<pre class="brush: csharp;">
    lock (workerLocker)
    {
      runningWorkers--;
      Monitor.Pulse (workerLocker);
    }
</pre>
<p>And when the running number of workers reaches zero, the monitor exist the wait condition and the main thread continues.</p>
<p>The wait on the locker object forms a barrier in the example above. The method illustrated here is simple and elegant. It can be used to create the barriers needed to synchronize the clock event mentioned earlier.</p>
<p>Threadpooling might not always be the optimal solution though. While the number of threads in a thread pool is typically bounded to a few dozens, it may incur excessive context switching penalties if the majority of the threads are CPU bound. In a computation intensive situation, a fixed number of threads approximating the number of computational cores would be more appropriate (for instance, four threads on a four core CPU).</p>
<p>Here I will show another relatively simple way to construct a barrier where only a predetermined maximum number of threads can reach at a given time. To achieve such a ceiling, a global semaphore is used (in this example three concurrent threads can enter the semaphore):</p>
<pre class="brush: csharp;">
public class Global
{
    public static Semaphore sp = new Semaphore(3, 3);
}
</pre>
<p>To simplify coding and shield the programmer from the synchronization mechanism details, I created an <strong>IEvent</strong> interface and an abstract <strong>EventBase</strong> as follows:</p>
<pre class="brush: csharp;">
interface IEvent
{
    void OnEvent(int arg);
}
</pre>
<pre class="brush: csharp;">
public abstract class EventBase : IEvent
{
    #region IEvent Members
    public void OnEvent(int arg)
    {
        Global.sp.WaitOne();
        Run(arg);
        Global.sp.Release();
    }
    #endregion

    public virtual void Run(int arg)
    {
    }
}
</pre>
<p>Users can simply implement their code that needs to block at the barrier by inheriting from <strong>EventBase</strong> and overridding the <strong>Run()</strong> method:</p>
<pre class="brush: csharp;">
public class Event1 : EventBase
{
    public override void Run(int arg)
    {
        Console.WriteLine(&quot;Thread {0}, arg {1}&quot;, Thread.CurrentThread.ManagedThreadId, arg);
        Thread.Sleep(1000);
    }
}
</pre>
<p>To illustrate how this barrier implementation can be used considering the following code:</p>
<pre class="brush: csharp;">
class Program
{
    delegate void MyEvent(int arg);

    static void Main(string[] args)
    {
        IEvent e = new Event1();
        MyEvent m = new MyEvent(e.OnEvent);

        List&lt;IAsyncResult&gt; l = new List&lt;IAsyncResult&gt;();

        for (int i = 0 ; i &lt; 6 ; i++)
        {
          IAsyncResult r = m.BeginInvoke(i, null, null);
          l.Add(r);
        }

        foreach (IAsyncResult r in l)
        {
            m.EndInvoke(r);
        }
    }
}
</pre>
<p>In the code above, we simulate six concurrent threads that need to be synchronized. The multi-threading is achieved via asynchronous invocation. Because the capacity of the semaphore is set to be 3 in this example and if this code is run on a quad-core machine, you will see that the six asynchronous threads are run in two batches, three at a time. And all the threads are synchronized at the end. Here is the sample output:</p>
<blockquote><p>
Thread 10, arg 1<br />
Thread 11, arg 2<br />
Thread 6, arg 0<br />
Thread 13, arg 4<br />
Thread 10, arg 5<br />
Thread 12, arg 3
</p></blockquote>
<p>Using this approach, the number of concurrently running threads can be precisely controlled by the maximum threads allowed in the semaphore.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/11/27/a-simple-thread-barrier-implementation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Simple Program for Finding Palindromic Prime Numbers</title>
		<link>http://www.kerrywong.com/2009/11/15/a-simple-program-for-finding-palindromic-prime-numbers/</link>
		<comments>http://www.kerrywong.com/2009/11/15/a-simple-program-for-finding-palindromic-prime-numbers/#comments</comments>
		<pubDate>Mon, 16 Nov 2009 01:49:08 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Palindromic Prime Number]]></category>
		<category><![CDATA[Palprime]]></category>
		<category><![CDATA[Prime Number]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1527</guid>
		<description><![CDATA[A palindromic prime (palprime) is a prime number that is also palindromic. So out of curiosity I wrote a simple program a few days ago that can find the palindromic numbers within a given range. Here is the code in C++:

#include &#60;stdio.h&#62;
#include &#60;stdlib.h&#62;
#include &#60;limits.h&#62;
#include &#60;math.h&#62;
#include &#60;iostream&#62;

using namespace std;

bool IsPrime(unsigned long long n) {
	bool r = [...]]]></description>
			<content:encoded><![CDATA[<p>A <a href="http://mathworld.wolfram.com/PalindromicPrime.html">palindromic prime</a> (palprime) is a prime number that is also palindromic. So out of curiosity I wrote a simple program a few days ago that can find the palindromic numbers within a given range. Here is the code in C++:<span id="more-1527"></span></p>
<pre class="brush: cpp;">
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;limits.h&gt;
#include &lt;math.h&gt;
#include &lt;iostream&gt;

using namespace std;

bool IsPrime(unsigned long long n) {
	bool r = true;

	for (unsigned long long i = 3; i &lt; sqrt((double) n) + 1; i+= 2)
	{
		if (n % i ==0) {
			r = false;
			break;
		}
	}

	return r;
}

bool IsPalindrome(unsigned long long n) {
	bool r = true;
	char s[30];
	int l = sprintf(s, &quot;%llu&quot;, n);

	if (l == 1 &amp;&amp; n != 1) {
		r = true;
	} else	{
		for (int i = 0; i &lt; l/2; i++) {
			if (s[i] != s[l-i-1]) {
				r = false;
				break;
			}
		}
	}

	return r;
}

/*
 * usage: palprime [lbound] [ubound]
 */
int main(int argc, char** argv) {
	unsigned long long beginNum = 3;
	unsigned long long endNum = 3;

	if (argc == 2) { // lbound default to 3
#ifdef _WIN32
		endNum = _strtoui64(argv[1], NULL, 10);
#else
		endNum = strtoull(argv[1], NULL, 10);
#endif

	} else if (argc == 3) {
#ifdef _WIN32
		beginNum = _strtoui64(argv[1], NULL, 10);
		endNum = _strtoui64(argv[2], NULL, 10);
#else
		beginNum = strtoull(argv[1], NULL, 10);
		endNum = strtoull(argv[2], NULL, 10);
#endif
	}

        unsigned long long i = beginNum;

        while (i &lt; endNum) {
                char s[30];
                int l = sprintf(s, &quot;%llu&quot;, i);

		//length cannot be even as even length palindrome numbers
		//can be divided by 11.
                if (l % 2 == 0) {
                    i = ((unsigned long long) (i / 10)) * 100 + 1;
                    continue;
                }

		if (IsPalindrome(i)) {
			if (IsPrime(i)) {
				cout &lt;&lt; i &lt;&lt; endl;
			}
		}

                i+=2;

                if (s[0] % 2 == 0) {
                    i+=pow(10, l-1);

		    //leading/ending number cannot be 5
                    if (((int) (s[0] - '0')) + 1 == 5) {
                        i += 2 * pow(10, l-1);
                    }
                }
	}
	return (EXIT_SUCCESS);
}
</pre>
<p>At first, I was trying to find all the palprimes that can be represented by 64 bit integers. But soon I realized that it would take months to do so using the code above with a quad-core PC (using 4 processes with different ranges). Anyway, here&#8217;s the last few palindromic primes less than 10,000,000,000,000:</p>
<blockquote><p>
9999899989999<br />
9999901099999<br />
9999907099999<br />
9999913199999<br />
9999919199999<br />
9999938399999<br />
9999961699999<br />
9999970799999<br />
9999980899999<br />
9999987899999
</p></blockquote>
<p>And here are a few interesting ones:</p>
<blockquote><p>
11357975311<br />
1112345432111<br />
1300000000031<br />
1700000000071<br />
1900000000091<br />
7900000000097<br />
9200000000029<br />
1357900097531
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/11/15/a-simple-program-for-finding-palindromic-prime-numbers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CFL Capacitor Problem</title>
		<link>http://www.kerrywong.com/2009/11/08/cfl-capacitor-problem/</link>
		<comments>http://www.kerrywong.com/2009/11/08/cfl-capacitor-problem/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 02:03:01 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Compact Fluorescent Lamp]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1511</guid>
		<description><![CDATA[Many of you may still remember the capacitor plague that caused massive motherboard failures back in the early 2000s. While the practice of using cheap and unreliable electrolytic capacitors in computer components has largely died down nowadays, it seems that the issue has cropped up elsewhere. 
This time,  the issue is with cheap capacitors [...]]]></description>
			<content:encoded><![CDATA[<p>Many of you may still remember the <a href="http://en.wikipedia.org/wiki/Capacitor_plague">capacitor plague</a> that caused massive motherboard failures back in the early 2000s. While the practice of using cheap and unreliable <a href="http://en.wikipedia.org/wiki/Electrolytic_capacitor">electrolytic capacitors</a> in computer components has largely died down nowadays, it seems that the issue has cropped up elsewhere. <span id="more-1511"></span></p>
<p>This time,  the issue is with cheap capacitors used in some compact fluorescent light (CFL) bulbs. The following photo is taken from the electronic ballast of a CFL that failed during the first year of its use:<br />
<div id="attachment_1516" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/11/badcap.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/11/badcap.jpg" alt="Bad Capacitor in CFL electronic ballast" title="Bad Capacitor in CFL electronic ballast" width="320" height="398" class="size-full wp-image-1516" /></a><p class="wp-caption-text">Bad Capacitor in CFL electronic ballast</p></div></p>
<p>As you can see that the bulging top clearly shows signs of leakage. The capacitor used in this particular CFL is rated 22uf/200V with a maximum operating temperature of 105 degree (Celsius). Under normal conditions, this capacitor should be fine. But with a lot of interior light fixtures that are recessed into the ceiling, the heat generated during normal operation can easily approach this limit and causes the CFL to fail prematurely. Many failed CFLs I had over the past few years exhibited similar capacitor problems. And apparently, the general quality issue of CFLs <a href="http://www.nytimes.com/2009/03/28/business/energy-environment/28bulbs.html">has been concerning</a>.</p>
<p>It seems to me though that the easiest way to fix this issue is for manufacturers to use electrolytic capacitors with higher operating temperature rating and lower <a href="http://en.wikipedia.org/wiki/Equivalent_series_resistance">ESR</a>. Since the majority of CFL electronic ballasts utilize only one electrolytic capacitor, the increase in cost should be minimum.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/11/08/cfl-capacitor-problem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Weekend Ubuntu Upgrade</title>
		<link>http://www.kerrywong.com/2009/11/01/weekend-ubuntu-upgrade/</link>
		<comments>http://www.kerrywong.com/2009/11/01/weekend-ubuntu-upgrade/#comments</comments>
		<pubDate>Mon, 02 Nov 2009 00:52:16 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Linux/BSD]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1504</guid>
		<description><![CDATA[Karmic Koala was released into the wild last Thursday, so naturally I was going to upgrade my desktop installations at home. In this past I had been doing fresh installs whenever there was a new release, since there might be some issues with the new Ext4 file system, I decided to upgrade my current 9.04 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://releases.ubuntu.com/karmic/">Karmic Koala</a> was released into the wild last Thursday, so naturally I was going to upgrade my desktop installations at home. In this past I had been doing fresh installs whenever there was a new release, since there might be <a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/453579">some issues</a> with the new Ext4 file system, I decided to upgrade my current 9.04 installation in place and perform a fresh installation when the Ext4 file system stabilizes.<span id="more-1504"></span></p>
<p>Since I had quite a few unofficial packages installed on my primary PC, I was not quite sure how the upgrade would turn out and I was prepared to see a few gotchas at some point. But the upgrade process was surprisingly smooth (albeit slow since all new versions of the installed packages had to be fetched first), and when the upgrade process is done I was able to boot into the new desktop. The only thing I needed to do was to re-install the <a href="http://www.nvidia.com/object/cuda_get.html">CUDA driver</a> (190.18), but this was to be expected since every major kernel updates would require the CUDA driver to be re-installed. I certainly hope that NVidia would make their proprietary binary drivers  more robust by detecting kernel changes and reinstall automatically if necessary as opposed to require the end user&#8217;s manual intervention. </p>
<p>For my other machine running Ubuntu 9.04, the upgrade was equally smooth. One of the problems I ran into there was due to my VMWare Server installation. As it turned out, there are <a href="http://www.uluga.ubuntuforums.org/showthread.php?t=1305254">some issues</a> with the default installation package that came with VMWare Server 2. The problem however can be resolved with <a href="http://radu.cotescu.com/2009/10/30/how-to-install-vmware-server-2-0-x-on-ubuntu-9-10-karmic-koala/">Radu&#8217;s installation script</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/11/01/weekend-ubuntu-upgrade/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows Administrative Share With Samba</title>
		<link>http://www.kerrywong.com/2009/10/04/windows-administrative-share-with-samba/</link>
		<comments>http://www.kerrywong.com/2009/10/04/windows-administrative-share-with-samba/#comments</comments>
		<pubDate>Sun, 04 Oct 2009 17:55:33 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Linux/BSD]]></category>
		<category><![CDATA[Samba]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1482</guid>
		<description><![CDATA[In a heterogeneous computing environment (e.g. Linux and Windows), it is necessary to use Samba to share files between the Linux systems and Windows systems. Due to the security enhancements in Windows XP SP2 and above however, the administrative share access (e.g. \\{computer name}\c$ is disabled by default.
To enable administrative share access from Linux hosts, [...]]]></description>
			<content:encoded><![CDATA[<p>In a heterogeneous computing environment (e.g. Linux and Windows), it is necessary to use <a href="http://samba.org/">Samba</a> to share files between the Linux systems and Windows systems. Due to the security enhancements in Windows XP SP2 and above however, the administrative share access (e.g. \\{<strong><em>computer name</em></strong>}\c$ is disabled by default.<span id="more-1482"></span></p>
<p>To enable administrative share access from Linux hosts, we need to change the Windows machine&#8217;s security policy. My assumption is that you are using Windows XP. You may need to make further changes depending on the version of Windows you are using.</p>
<p>The security policy snap-in is located at </p>
<blockquote><p>c:\windows\system32\secpol.msc</p></blockquote>
<p>Select local policies and then Security Options:<br />
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/10/security_setting.gif"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/10/security_setting.gif" alt="security_setting" title="security_setting" width="600" height="424" class="aligncenter size-full wp-image-1496" /></a><br />
Then select sharing and security model for local accounts:<br />
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/10/security_setting_1.gif"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/10/security_setting_1.gif" alt="security_setting_1" title="security_setting_1" width="418" height="505" class="aligncenter size-full wp-image-1495" /></a></p>
<p>Under the enhanced security scheme, &#8220;Guest only: local users authenticate as guests&#8221; is chosen. This policy means that administrative network access is treated as if it was done with a guest account and therefore you would get permission denied error when trying to access an administrative share &#8212; even though your account has administrative rights locally.</p>
<p>To allow administrative share on Samba network, you can simply select the other option &#8220;Classic: local users authenticate as themselves&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/10/04/windows-administrative-share-with-samba/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An Alternative Illustration of Prime Number Distribution</title>
		<link>http://www.kerrywong.com/2009/09/06/an-alternative-illustration-of-prime-number-distribution/</link>
		<comments>http://www.kerrywong.com/2009/09/06/an-alternative-illustration-of-prime-number-distribution/#comments</comments>
		<pubDate>Sun, 06 Sep 2009 14:40:04 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Distribution]]></category>
		<category><![CDATA[Histogram]]></category>
		<category><![CDATA[Prime Number]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1441</guid>
		<description><![CDATA[Prime number theorem dictates the asymptotic behavior of prime number distributions. In layman terms, the distance between prime numbers increases at a logarithmic pace. This gives the familiar logarithm figure.
Alternatively, if we “bin” the prime numbers according to the differences (gaps) between two consecutive prime numbers, we would yield another logarithmic distribution: the histogram of [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Prime_number_theorem">Prime number theorem</a> dictates the asymptotic behavior of prime number distributions. In layman terms, the distance between prime numbers increases at a logarithmic pace. This gives the familiar logarithm figure.<span id="more-1441"></span></p>
<p>Alternatively, if we “bin” the prime numbers according to the differences (gaps) between two consecutive prime numbers, we would yield another logarithmic distribution: the histogram of such differences will be logarithmic as well.</p>
<p>So, take the following sequence of prime numbers for example:</p>
<blockquote><p>2, 3, 5, 7, 11, 13, 17, 19, 23, 29&#8230;</p></blockquote>
<p>The distances between the consecutive numbers in the above sequence are:</p>
<blockquote><p>
3-2 = 1<br />
5-3 = 2<br />
7-5 = 2<br />
11-7 = 4<br />
19-17 = 2<br />
23-19 = 4<br />
29-23 = 6
</p></blockquote>
<p>We then calculate the histogram based on the gaps. </p>
<p>Denote the histogram bin index as<br />
\[i = \lfloor\frac{d}{2}\rfloor\]</p>
<p>For the example above, we get the following distributions for H[i]:<br />
\[H[0] = 1, H[1] = 3 H[2]=2, H[3]=1\]</p>
<p>Now we calculate the distribution (H[i]) described above using prime numbers within the following interval (for all prime numbers up to 4,294,967,291):<br />
\[[2^0, 2^{32}]\]</p>
<p>We can obtain the following plot for the histogram (H[i]):<br />
<div id="attachment_1474" class="wp-caption aligncenter" style="width: 610px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/09/hist.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/09/hist.jpg" alt="Prime number distribution" title="Prime number distribution" width="600" height="450" class="size-full wp-image-1474" /></a><p class="wp-caption-text">Prime number distribution</p></div></p>
<p>To illustrate that the distribution is indeed around a logarithm curve, we take the logrithms of the values for each H[i] and get the following figure:</p>
<div id="attachment_1475" class="wp-caption aligncenter" style="width: 610px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/09/hist_log.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/09/hist_log.jpg" alt="Prime number distribution" title="Prime number distribution" width="600" height="450" class="size-full wp-image-1475" /></a><p class="wp-caption-text">Prime number distribution</p></div>
<p>As you can see, the distribution is around a straight line.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/09/06/an-alternative-illustration-of-prime-number-distribution/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Why Current EVs Do Not Make Sense From Economical And Environmental View Points</title>
		<link>http://www.kerrywong.com/2009/08/15/why-current-evs-do-not-make-sense-from-economical-and-environmental-view-points/</link>
		<comments>http://www.kerrywong.com/2009/08/15/why-current-evs-do-not-make-sense-from-economical-and-environmental-view-points/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 23:32:49 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Electric Vehicle]]></category>
		<category><![CDATA[Hybrid Car]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1432</guid>
		<description><![CDATA[About two years ago, I blogged about why hybrids were not saving us any energy by taking into consideration the amount of energy needed to produce the vast battery packs and the inherent low efficiencies in battery technologies.
Now, two years later after crude oil price peeked and then stabilized amidst the economic turmoil, the main [...]]]></description>
			<content:encoded><![CDATA[<p>About two years ago, I blogged about <a href="/2007/04/30/do-hybrid-cars-really-save-energy/">why hybrids were not saving us any energy</a> by taking into consideration the amount of energy needed to produce the vast battery packs and the inherent low efficiencies in battery technologies.<span id="more-1432"></span></p>
<p>Now, two years later after crude oil price peeked and then stabilized amidst the economic turmoil, the main reason for companies from Toyota and GM alike to push for new electric and hybrid vehicles seems to me is to show case their technological capabilities and ride along the buzz generated many years ago when the first generation Prius first hit the road. Using the technologies available to us today and in the immediate future, the advantage in terms of environmental impacts of these alternative vehicles such as the hybrid and electric cars remains unclear. And at their current state, it is doubtful that these alternative drivetrains make any economical sense.</p>
<p>Take electric cars for example. From an environmental point of view, while electrical vehicles by themselves do not generate any greenhouse emissions like their gasoline and diesel counterparts, the manufacturing process of the batteries that go into these EVs are likely to have a high environmental impact. The extraction of precious metals and the creation of some of the chemical compounds that used in these high energy density battery packs are likely to consume more energy than the well established process for engine manufacturing. And much of that energy is coming from electrical power plants that use fossil fuel for electricity generation. The “cleaner” nature of EVs is merely because of the redistribution of pollution over different stages of their life cycles and over different geographic areas.</p>
<p>From an economical stand point, today’s manufacturing processes to produce batteries used in the electrical vehicles remain very expensive and the cost of which constitutes a significant portion of the overall cost of the vehicle. And because batteries must be plugged into the grid for charging, it relies on the cost of electricity in order to make economical sense. It seems funny to me that at a time when people prefer natural gas based heating system and shy away from electrical baseboards due to cost considerations, it would somehow be cheaper to charge the EVs off the grid on a daily basis. We know that the power requirement for the electrical vehicles dwarfs some of the most power hungry household electrical systems. Until we are further removed from fossil fuels in our electricity generation process, the cost saving of using EVs is hardly justified. We are having the illusion of savings due to government subsidy and the lower day-to-day operating expenses. The initial investment buying an EV, however, is likely to be much bigger than that of a traditional gasoline counterpart.</p>
<p>Reliability remains a big concern for EVs and hybrids, particularly for EVs. As I discussed <a href="/2007/04/30/do-hybrid-cars-really-save-energy/">before</a>, given the complexity of the hybrid powertrains and the inherent reliability issues of the battery banks, it remains unknown how the long-term reliability (e.g. over a time span of 20 years) of these EVs compare against that of the more traditional vehicles. So even though electric motors are generally much more reliable than gasoline engines, the current state of battery technology significantly limits the overall reliability of these battery powered vehicles.</p>
<p>Another not-so-obvious problem of EVs is related to the power-hungry auxiliary systems (e.g. Heater, air conditioner, audio amplifier, etc). Using these systems will significantly shorten the advertised range and EVs may have to rely on an alternative power-generating unit (e.g. a regular gas powered motor) to generate the additional power needed while using these auxiliary systems. </p>
<p>To improve EV performance, companies have invested heavily and concentrated on reducing the overall weight of the vehicles by using lighter materials such as carbon fibers for the body frames. If we were to adopt a similar approach in today’s gasoline car manufacturing process and reduce the weight of the vehicles, we would significantly reduce the power requirement and thus be able to reduce the engine sizes and ultimately reduce emissions as well.</p>
<p>So, the long term viability of the current electrical vehicles remains to be seen.</p>
<h3>References:</h3>
<ul>
<li>
<a href="http://money.cnn.com/2009/08/11/autos/volt_mpg/index.htm?postversion=2009081108">Chevy volt to get 230 mpg rating</a>
</li>
<li>
<a href="http://tech.slashdot.org/comments.pl?sid=1332901">Slashdot comments</a> on Chevy Volt Rated At 230 mpg In the City
</li>
<li>
<a href="http://www.evworld.com/article.cfm?storyid=1361">Electric Vehicles and the Environment</a>
</li>
<li>
<a href="http://www.typesofenergy.co.uk/electric-vehicles-environment.html">http://www.typesofenergy.co.uk/electric-vehicles-environment.html</a>
</li>
<li>
<a href="http://agmetalminer.com/2009/08/12/a-different-take-on-the-gm-volt-announcement/">A Different Take on the GM Volt Announcement</a>
</li>
<li>
<a href="http://clipmarks.forbes.com/2009/08/11/chevy-volt-part-ii-mileage-but-at-what-cost/">Chevy Volt (part II): 230 MPG, but at what cost?</a>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/08/15/why-current-evs-do-not-make-sense-from-economical-and-environmental-view-points/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Strange Windows Authentication Behavior</title>
		<link>http://www.kerrywong.com/2009/07/30/strange-windows-authentication-behavior/</link>
		<comments>http://www.kerrywong.com/2009/07/30/strange-windows-authentication-behavior/#comments</comments>
		<pubDate>Thu, 30 Jul 2009 12:13:59 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1429</guid>
		<description><![CDATA[I was writing an ASP.Net 2.0 web application using Windows authentication (since I needed to capture users’ credentials). The web application saves data into a MS SQL 2005 database using a SQL server account. While developing this application, I ran into a very strange issue.
Since the database access is using a SQL Server account rather [...]]]></description>
			<content:encoded><![CDATA[<p>I was writing an ASP.Net 2.0 web application using Windows authentication (since I needed to capture users’ credentials). The web application saves data into a MS SQL 2005 database using a SQL server account. While developing this application, I ran into a very strange issue.<span id="more-1429"></span></p>
<p>Since the database access is using a SQL Server account rather than integrated authentication, in theory the database access code should not be affected by whether I use Forms authentication or Windows authentication in the web application. </p>
<p>However, the problem I ran into was that if I use Forms authentication mode, everything works fine. But if I switch the authentication mode to Windows, I would get the following error message emitted from the data access layer after the application was deployed to the server:</p>
<blockquote><p>A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 &#8211; Could not open a connection to SQL Server) </p></blockquote>
<p>What is weirder is that if I tried to use the application locally on the web server after deployment, everything would work fine. And after &#8220;touching&#8221; the deployed website on the server, the web pages can then be remotely accessed via client browser for a while (10 minutes maybe) but after that the same error would occur again.</p>
<p>So I searched many forums but could not find any conclusive explanations or remedies.</p>
<h3>The Not So Satisfying Solution</h3>
<p>One of my coworkers took a look at my code and confirmed that there were no coding errors but noticed that I did not have port information in the connection string (Note, even though we use non-standard ports, this has never been necessary). So as he suggested, I plugged in the port number and it worked!</p>
<p>Clearly, I am still as confused as before. The authentication modes differences must have somehow affected the way the connection string is interpreted&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/07/30/strange-windows-authentication-behavior/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Monodevelop on Ubuntu 9.04</title>
		<link>http://www.kerrywong.com/2009/07/22/monodevelop-on-ubuntu-9-04/</link>
		<comments>http://www.kerrywong.com/2009/07/22/monodevelop-on-ubuntu-9-04/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 04:00:04 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Linux/BSD]]></category>
		<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[C Sharp (C#)]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1408</guid>
		<description><![CDATA[I am running Ubuntu 9.04 64bit. One thing I noticed is that the integrated debugger is behaving quite flaky for the included Monodevelop 2.0 package. After some research, it turned out that a lot of people are having similar issues.
So I followed the instructions given in these two blogs: Install Mono 2.4 on Ubuntu,
Building Mono [...]]]></description>
			<content:encoded><![CDATA[<p>I am running Ubuntu 9.04 64bit. One thing I noticed is that the integrated debugger is behaving quite flaky for the included <a href="http://monodevelop.com/">Monodevelop 2.0</a> package. After some research, it turned out that a lot of people are having similar issues.<span id="more-1408"></span></p>
<p>So I followed the instructions given in these two blogs: <a href="http://blog.ruski.co.za/page/Install-Mono-on-Ubuntu.aspx">Install Mono 2.4 on Ubuntu</a>,<br />
<a href="http://synpl.blogspot.com/2009/07/building-mono-and-monodevelop-from.html">Building Mono and MonoDevelop from source on Ubuntu 9.04 64bit</a> to re-install Monodevelop 2.0 and its dependencies from the source. </p>
<p>One thing you will need to pay special attention to is that for the monodevelop-debugger-mdb-2.0 to compile successfully, you will need mono-debugger version 2.4, instead of the latest version 2.4.1. Otherwise you will receive an error on <em>Thread.AbortInvocation</em> as there is a breaking change in mono-debugger 2.4.1 which added a parameter to the method (see <a href="http://lists.ximian.com/pipermail/mono-patches/2009-May/149225.html">mono debugger 2.4.1 change log</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/07/22/monodevelop-on-ubuntu-9-04/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Poor Man&#8217;s Parallel Task Dispatcher</title>
		<link>http://www.kerrywong.com/2009/07/14/poor-mans-parallel-task-dispatcher/</link>
		<comments>http://www.kerrywong.com/2009/07/14/poor-mans-parallel-task-dispatcher/#comments</comments>
		<pubDate>Wed, 15 Jul 2009 01:55:39 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[C Sharp (C#)]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Multi-threading]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1392</guid>
		<description><![CDATA[Even though multi-core processors are almost ubiquitous nowadays, applications are slow to catch up. Of course, one could always re-write the applications in order to take the full advantages in a multi-core environment. But it is not an easy undertaking. For applications that performs rather repetitive tasks over a well defined set of data (e.g. [...]]]></description>
			<content:encoded><![CDATA[<p>Even though multi-core processors are almost ubiquitous nowadays, applications are slow to catch up. Of course, one could always re-write the applications in order to take the full advantages in a multi-core environment. But it is not an easy undertaking.<span id="more-1392"></span> For applications that performs rather repetitive tasks over a well defined set of data (e.g. image processing) it is relatively easy to utilize multiple cores with some simple modifications to the applications themselves. </p>
<p>For the type of applications that perform the same task over a large dataset for example,</p>
<pre class="brush: csharp;">
for (int i = 0 ; i &lt; num ; i++)
{
    //lengthy tasks
}
</pre>
<p>we could easily break down the <em>for loop</em> evenly into chunks that fit into the number of processors given. And for each of the subsets we could create a new process to perform the desired tasks. For instance, if we were to execute the above <em>for loop</em> in parallel on a duo-core processor, we could re-write each of the loops like the following:</p>
<pre class="brush: csharp;">
//core 1
for (int i = 0 ; i &lt; num ; i+=2)
{
    //lengthy tasks
}
</pre>
<pre class="brush: csharp;">
//core 2
for (int i = 1 ; i &lt; num ; i+=2)
{
    //lengthy tasks
}
</pre>
<p>By executing the application in separate processes, we eliminated certain race conditions that must be properly handled in a multi-threaded process and thus it is far easier to execute multiple processes concurrently when there is no inter-process communications involved than to handle multi-processing within a process via multi-threading. In a multi-process scenario, the operating system handles the concurrency issue behind the scene whereas in the multi-threading case the application developer must ensure the code regions are thread safe.</p>
<p>The following C# code shows how to dispatch tasks among different processes using asynchronous method invocations. Each process being invoked can identify its order by the extra integer parameter (line 36) passed to it. Thus we only needed to modify the target application to take this extra parameter into account (for instance, in a quad-core system, the first process would process items 1,5,9&#8230; and the second process would run items 2,6,10, and so on)</p>
<pre class="brush: csharp;">
using System;
using System.Diagnostics;
using System.Threading;

namespace MPDispatcher
{
    class Program
    {
        public delegate bool CmdDlg(string fn, string args);

        private bool RunCommand(string fn, string args)
        {
            bool r = true;
            Process p = new Process();

            p.StartInfo.FileName = fn;
            p.StartInfo.Arguments = args;

			Console.WriteLine(String.Format(&quot;Starting {0} with arguments {1}. Thread ID: {2}&quot;, fn, args, Thread.CurrentThread.ManagedThreadId));
            r = p.Start();
            p.WaitForExit();

            return r;
        }

		public bool DispatchCommand(int numOfThreads, string args)
        {
            bool r = true;

            IAsyncResult[] ars = new IAsyncResult[numOfThreads];
            CmdDlg[] dlgs = new CmdDlg[numOfThreads];

            for (int i = 0; i &lt; numOfThreads; i++)
            {
                dlgs[i] = new CmdDlg(RunCommand);
                ars[i] = dlgs[i].BeginInvoke(args, i.ToString(), null, null);
				Thread.Sleep(100);
            }

            bool finished = false;

			//wait till all processes are finished.
            while (!finished)
            {
                bool t = true;

                for (int i = 0; i &lt; numOfThreads; i++)
                    t = t &amp;&amp; ars[i].IsCompleted;   

                if (t) finished = true;

                Thread.Sleep(100);
            }

            for (int i = 0; i &lt; numOfThreads; i++)
            {
                r = r &amp;&amp; dlgs[i].EndInvoke(ars[i]);
            }

            return r;
        }

        static void Main(string[] args)
        {
            Program p = new Program();

			if (args.Length &lt; 1 || args[0].ToUpper() == &quot;-H&quot;) {
				Console.WriteLine(&quot;Usage: MPDispatcher {app name} {app args}&quot;);
			} else {
				int numThreads = 4; //use 4 threads
				string argStr = string.Empty;

				for (int i = 1 ; i &lt; args.Length; i++) {
					argStr = String.Format(&quot;{0} {1}&quot;, argStr, args[i]);
				}

            	p.DispatchCommand(numThreads, argStr);
			}
        }
    }
}
</pre>
<p>The above code works under Windows and Linux (Mono). </p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/07/14/poor-mans-parallel-task-dispatcher/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Finance Down Earlier Today</title>
		<link>http://www.kerrywong.com/2009/07/06/google-finance-down-earlier-today/</link>
		<comments>http://www.kerrywong.com/2009/07/06/google-finance-down-earlier-today/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 01:43:56 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Cloud Computing]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1368</guid>
		<description><![CDATA[It appeared that Google Finance was down for at least half an hour (from before 9:30 EST till after 10:00 EST) today. I captured this screen-shot during the outage:
This is just the latest one of a string of high-profile outages from large corporations like Google (here&#8217;s an other outage less than two months ago) and [...]]]></description>
			<content:encoded><![CDATA[<p>It appeared that Google Finance was down for at least half an hour (from before 9:30 EST till after 10:00 EST) today. I captured this screen-shot during the outage:<span id="more-1368"></span></p>
<div id="attachment_1369" class="wp-caption aligncenter" style="width: 686px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/googlefinanceerror1.gif"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/googlefinanceerror1.gif" alt="Google Finance Error" title="Google Finance Error" width="676" height="445" class="size-full wp-image-1369" /></a><p class="wp-caption-text">Google Finance Error</p></div>
<p>This is just the latest one of a string of high-profile outages from large corporations like Google (<a href="http://news.cnet.com/widespread-google-outages-rattle-users/">here&#8217;s an other outage less than two months ago</a>) and Microsoft (<a href="http://news.cnet.com/8301-1023_3-10279084-93.html">this outage</a> was on July 3, due to fire at a data center in Seattle).</p>
<p>It certainly does not bode well for those who tout <a href="http://en.wikipedia.org/wiki/Cloud_computing">cloud computing</a>. While in theory, larger cloud service providers like Google and Microsoft have the resources and capabilities to make their cloud services much more reliable. In practice, it doesn&#8217;t help when the services are down at the most unfortunate time when you need them the most.</p>
<p>I could see some benefits of using cloud computing in some non-essential business scenarios, but I doubt that any business would shift its core applications into the cloud. The reason is quite simple: For the bread-and-butter business applications, we need to know with confidence when the system will be down. When you host your own application, even if you don&#8217;t have control over everything (e.g. hardware failure) you at least can control when you implement changes. So while your applications might not be up 99% of the time, you could carefully plan the outage windows for the necessary maintenances to minimize any side effects to the normal business operations. </p>
<p>Of course, there are many other reasons why companies should not en-thrust their core businesses to the cloud. Some of the reasons are physical (e.g. a web service call will always be magnitudes slower than a in-process function call. And Internet speed will always be slower than intranet and significantly slower than memory speed), and some are philosophical. Like <a href="http://en.wikipedia.org/wiki/Richard_Stallman">Richard Stallman</a> once <a href="http://www.guardian.co.uk/technology/2008/sep/29/cloud.computing.richard.stallman">put it</a>:</p>
<blockquote><p>&#8220;One reason you should not use web applications to do your computing is that you lose control. It&#8217;s just as bad as using a proprietary program. Do your own computing on your own computer with your copy of a freedom-respecting program. If you use a proprietary program or somebody else&#8217;s web server, you&#8217;re defenseless. You&#8217;re putty in the hands of whoever developed that software.&#8221;</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/07/06/google-finance-down-earlier-today/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Image Blur Detection via Hough Transform &#8212; IV</title>
		<link>http://www.kerrywong.com/2009/07/03/image-blur-detection-via-hough-transform-iv/</link>
		<comments>http://www.kerrywong.com/2009/07/03/image-blur-detection-via-hough-transform-iv/#comments</comments>
		<pubDate>Sat, 04 Jul 2009 01:06:30 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[Blur Detection]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Edge Detection]]></category>
		<category><![CDATA[Hough Transform]]></category>
		<category><![CDATA[Intel IPP]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1277</guid>
		<description><![CDATA[In my previous three articles (1,2,3) I discussed how to use Canny edge detection and Hough transform to identify blur images. Here I will show some results from the algorithm discussed before.
Results
When presented with images that are clear, the algorithm correctly identified most of them (see images below):
















The following images illustrate how the original image [...]]]></description>
			<content:encoded><![CDATA[<p>In my previous three articles (<a href="/2009/06/19/image-blur-detection-via-hough-transform-i/">1</a>,<a href="/2009/06/24/image-blur-detection-via-hough-transform-ii/">2</a>,<a href="/2009/06/27/image-blur-detection-via-hough-transform-iii/">3</a>) I discussed how to use Canny edge detection and Hough transform to identify blur images. Here I will show some results from the algorithm discussed before.<span id="more-1277"></span></p>
<h3>Results</h3>
<p>When presented with images that are clear, the algorithm correctly identified most of them (see images below):</p>
<table>
<tr>
<td>
<div id="attachment_1285" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c1.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c1.jpg" alt="Building (Microsoft Research Digital Image)" title="Building (Microsoft Research Digital Image)" width="320" height="240" class="size-full wp-image-1285" /></a><p class="wp-caption-text">Building (Microsoft Research Digital Image)</p></div>
</td>
<td>
<div id="attachment_1286" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c2.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c2.jpg" alt="Street (Microsoft Research Digital Image)" title="Street (Microsoft Research Digital Image)" width="320" height="240" class="size-full wp-image-1286" /></a><p class="wp-caption-text">Street (Microsoft Research Digital Image)</p></div>
</td>
</tr>
</table>
<table>
<tr>
<td>
<div id="attachment_1289" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c5.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c5.jpg" alt="Sky" title="Sky" width="320" height="240" class="size-full wp-image-1289" /></a><p class="wp-caption-text">Sky</p></div>
</td>
<td>
<div id="attachment_1288" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c4.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c4.jpg" alt="Flower" title="Flower" width="320" height="240" class="size-full wp-image-1288" /></a><p class="wp-caption-text">Flower</p></div>
</td>
</tr>
</table>
<p>The following images illustrate how the original image (top right) is divided into sub regions. Canny detection is performed on each of the sub images.</p>
<table>
<tr>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/1.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/1.jpg" alt="1" title="1" width="214" height="160" class="aligncenter size-full wp-image-1300" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/4.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/4.jpg" alt="4" title="4" width="214" height="160" class="aligncenter size-full wp-image-1303" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/7.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/7.jpg" alt="7" title="7" width="214" height="160" class="aligncenter size-full wp-image-1306" /></a>
</td>
</tr>
<tr>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/2.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/2.jpg" alt="2" title="2" width="214" height="160" class="aligncenter size-full wp-image-1301" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/5.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/5.jpg" alt="5" title="5" width="214" height="160" class="aligncenter size-full wp-image-1304" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/8.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/8.jpg" alt="8" title="8" width="214" height="160" class="aligncenter size-full wp-image-1307" /></a>
</td>
</tr>
<tr>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/3.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/3.jpg" alt="3" title="3" width="214" height="160" class="aligncenter size-full wp-image-1302" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/6.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/6.jpg" alt="6" title="6" width="214" height="160" class="aligncenter size-full wp-image-1305" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/9.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/9.jpg" alt="9" title="9" width="214" height="160" class="aligncenter size-full wp-image-1331" /></a>
</td>
</tr>
</table>
<p>When performing Hough Transform, I chose to detect up to ten lines in each image, with the following stepping parameter (the detection results are very sensitive to these parameters, the following parameters were chosen based on experiment results):<br />
\[\rho=1, \theta=0.01\]</p>
<p>Out of all the detected lines, a few sections are selected based on line continuity and the calculated average gradients around the detected lines. The following images shows the chosen Hough line segments based on the algorithm. </p>
<table>
<tr>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/1_o.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/1_o.jpg" alt="1_o" title="1_o" width="214" height="160" class="aligncenter size-full wp-image-1309" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/4_o.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/4_o.jpg" alt="4_o" title="4_o" width="214" height="160" class="aligncenter size-full wp-image-1312" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/7_o.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/7_o.jpg" alt="7_o" title="7_o" width="214" height="160" class="aligncenter size-full wp-image-1315" /></a>
</td>
</tr>
<tr>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/2_o.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/2_o.jpg" alt="2_o" title="2_o" width="214" height="160" class="aligncenter size-full wp-image-1310" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/5_o.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/5_o.jpg" alt="5_o" title="5_o" width="214" height="160" class="aligncenter size-full wp-image-1313" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/8_o.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/8_o.jpg" alt="8_o" title="8_o" width="214" height="160" class="aligncenter size-full wp-image-1316" /></a>
</td>
</tr>
<tr>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/3_o.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/3_o.jpg" alt="3_o" title="3_o" width="214" height="160" class="aligncenter size-full wp-image-1311" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/6_o.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/6_o.jpg" alt="6_o" title="6_o" width="214" height="160" class="aligncenter size-full wp-image-1314" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/9_o.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/9_o.jpg" alt="9_o" title="9_o" width="214" height="160" class="aligncenter size-full wp-image-1317" /></a>
</td>
</tr>
</table>
<p>The table below shows the gradient index calculated within each area (the average of the gradients along all the chosen line segments within a sub-image. The result is scaled by 1000, the scale factor is chosen such that for clear images the resulted index is greater than 1 and for blur images the resulted index is less than 1).</p>
<table>
<tr>
<td>1</td>
<td>1.709</td>
</tr>
<tr>
<td>2</td>
<td>2.383</td>
</tr>
<tr>
<td>3</td>
<td>1.012</td>
</tr>
<tr>
<td>4</td>
<td>2.842</td>
</tr>
<tr>
<td>5</td>
<td>3.389</td>
</tr>
<tr>
<td>6</td>
<td>2.419</td>
</tr>
<tr>
<td>7</td>
<td>2.933</td>
</tr>
<tr>
<td>8</td>
<td>2.168</td>
</tr>
<tr>
<td>9</td>
<td>2.534</td>
</tr>
</table>
<p>And the sub images are indexed as follows:</p>
<table>
<tr>
<td>1</td>
<td>4</td>
<td>7</td>
</tr>
<tr>
<td>2</td>
<td>5</td>
<td>8</td>
</tr>
<tr>
<td>3</td>
<td>6</td>
<td>9</td>
</tr>
</table>
<p>The algorithm can also detect images with deliberate blur regions (e.g. <a href="http://en.wikipedia.org/wiki/Bokeh">Bokeh</a>). The results are illustrated below:</p>
<div id="attachment_1287" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c3.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c3.jpg" alt="Plant (Microsoft Research Digital Image)" title="Plant (Microsoft Research Digital Image)" width="320" height="240" class="size-full wp-image-1287" /></a><p class="wp-caption-text">Plant (Microsoft Research Digital Image)</p></div>
<table>
<tr>
<td>1</td>
<td><font color="red">0.000</font></td>
</tr>
<tr>
<td>2</td>
<td>1.750</td>
</tr>
<tr>
<td>3</td>
<td>1.973</td>
</tr>
<tr>
<td>4</td>
<td>1.595</td>
</tr>
<tr>
<td>5</td>
<td>2.815</td>
</tr>
<tr>
<td>6</td>
<td>3.188</td>
</tr>
<tr>
<td>7</td>
<td><font color="red">0.000</font></td>
</tr>
<tr>
<td>8</td>
<td>1.204</td>
</tr>
<tr>
<td>9</td>
<td>1.308</td>
</tr>
</table>
<p>Note that the 0&#8217;s in the detection results indicate that within those regions, no lines could be reliably detected and thus those regions are considered blurred.<br />
Generally speaking, when an image contains both blurred and clear regions, some of the indexes will be zero and others will be greater than one.</p>
<p>The following images are detected as blurred, with the detected indexes far less than one.</p>
<table>
<tr>
<td>
<div id="attachment_1294" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/b3.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/b3.jpg" alt="Boat (Microsoft Research Digital Image)" title="Boat (Microsoft Research Digital Image)" width="320" height="240" class="size-full wp-image-1294" /></a><p class="wp-caption-text">Boat (Microsoft Research Digital Image)</p></div>
</td>
<td>
<div id="attachment_1295" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/b4.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/b4.jpg" alt="Candle" title="Candle" width="320" height="427" class="size-full wp-image-1295" /></a><p class="wp-caption-text">Candle</p></div>
</td>
</tr>
</table>
<h3>Limitations</h3>
<p>when image contrast is low, or when objects borders are not clearly defined, the algorithm may have difficulty in distinguishing whether an image is blurred. Take the following two cloud images for instance, the image on the left was correctly classified as a clear image due to the relatively high contrast around the center. But the image to the right was classified as blurred due to its lack of contrast. </p>
<table>
<tr>
<td>
<div id="attachment_1291" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/b1.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/b1.jpg" alt="Cloud" title="Cloud" width="320" height="240" class="size-full wp-image-1291" /></a><p class="wp-caption-text">Cloud</p></div>
</td>
<td>
<div id="attachment_1293" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/b2.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/b2.jpg" alt="Cloud" title="Cloud" width="320" height="240" class="size-full wp-image-1293" /></a><p class="wp-caption-text">Cloud</p></div>
</td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/07/03/image-blur-detection-via-hough-transform-iv/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Image Blur Detection via Hough Transform &#8212; III</title>
		<link>http://www.kerrywong.com/2009/06/27/image-blur-detection-via-hough-transform-iii/</link>
		<comments>http://www.kerrywong.com/2009/06/27/image-blur-detection-via-hough-transform-iii/#comments</comments>
		<pubDate>Sun, 28 Jun 2009 01:31:01 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[Blur Detection]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Edge Detection]]></category>
		<category><![CDATA[Hough Transform]]></category>
		<category><![CDATA[Intel IPP]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1231</guid>
		<description><![CDATA[I will continue where I left off in my previous post. After performing Hough transform, and extracted the longest sections of lines for each corresponding Hough line detected, we will need to calculate the gradients of the image pixels luminance around the line sections.
Gradient Calculation
If you remember how the Hough parameters were determined (in polar [...]]]></description>
			<content:encoded><![CDATA[<p>I will continue where I left off in my <a href="/2009/06/24/image-blur-detection-via-hough-transform-ii/">previous post</a>. After performing Hough transform, and extracted the longest sections of lines for each corresponding Hough line detected, we will need to calculate the gradients of the image pixels luminance around the line sections.<span id="more-1231"></span></p>
<h3>Gradient Calculation</h3>
<p>If you remember how the Hough parameters were determined (in polar form, see figure below), it is not difficult to obtain the pixel coordinates centered around the points on the detected line. </p>
<div id="attachment_1214" class="wp-caption aligncenter" style="width: 554px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/polar.png"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/polar.png" alt="Region selection for gradient calculation" title="Region selection for gradient calculation" width="544" height="410" class="size-full wp-image-1214" /></a><p class="wp-caption-text">Region selection for gradient calculation</p></div>
<p>In fact, we can formulate a line that is perpendicular to the line section detected during Hough transform, and use the line section that is within a predefined region (e.g. the between the dotted lines) to calculate the gradients of luminance. The following code snippet shows how the perpendicular line&#8217;s parameters are obtained.</p>
<pre class="brush: cpp;">
    /**
     * Get the equation parameters for the line that passes through (x,y) and is perpendicular
     * to the line specified by parameters (p0, theta0) in normal form.
     *
     * @param p0 : distance to line from origin.
     * @param theta0 : the slope of p0.
     * @param x : x coordinate of the point where the perpendicular line passes through
     * @param y : y coordinate of the point where the perpendicular line passes through
     * @param &amp;p : the perpendicular line's distance from origin.
     * @param &amp;theta : the slope of p.
     **/
    void LineUtils::GetPerpendicularLineParameters(float p0, float theta0, float x, float y, float &amp;p, float &amp;theta) {
        float x0 = p0 * cos(theta0);
        float y0 = p0 * sin(theta0);

        p = sqrt((x0 - x)*(x0 - x) + (y0 - y)*(y0 - y));

        float a1 = theta0 - PI / 2.0;
        float a2 = theta0 + PI / 2.0;

        //d=|x0 * cos a + y0 * sin a - p|
        float d1 = abs(x * cos(a1) + y * sin(a1) - p);
        float d2 = abs(x * cos(a2) + y * sin(a2) - p);

        if (d1 &lt; d2)
            theta = a1;
        else
            theta = a2;
    }
</pre>
<p>In an ideal situation, the gradient of the line points obtained via the method above looks like the figures below, where the edges are clearly identified. </p>
<div id="attachment_1254" class="wp-caption aligncenter" style="width: 570px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/edge1.png"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/edge1.png" alt="Edge (dark to bright)" title="Edge (dark to bright)" width="560" height="420" class="size-full wp-image-1254" /></a><p class="wp-caption-text">Edge (dark to bright)</p></div>
<div id="attachment_1255" class="wp-caption aligncenter" style="width: 570px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/edge2.png"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/edge2.png" alt="Edge (dark to bright to dark)" title="Edge (dark to bright to dark)" width="560" height="420" class="size-full wp-image-1255" /></a><p class="wp-caption-text">Edge (dark to bright to dark)</p></div>
<p>Sometimes, when the lighting condition is poor, the image would appear to be &#8220;grainy&#8221;, which sometimes led to poor line detection. For instance, the following figure shows the the gradient when the region around the detected edge is grainy:</p>
<div id="attachment_1258" class="wp-caption aligncenter" style="width: 570px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/noneedge.png"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/noneedge.png" alt="None-Edge" title="None-Edge" width="560" height="420" class="size-full wp-image-1258" /></a><p class="wp-caption-text">None-Edge</p></div>
<p>We use the number of times the luminance increases above or decreases below its mean along the perpendicular line interval as a measure of whether we accept the detection results as gradients or not. Typically when such number of crossings is less than 3 (see the first two images above) the curve is either monotonic or has a single peak, we assume that gradients can be correctly calculated and if the crossings are more than 3 we discard the results. The gradient is calculated as the slope of the curve. In the examples above, we used ten pixels on each side of the Hough line to calculate gradients.</p>
<h3>Image Regions</h3>
<p>For images with complex contents, it becomes difficult for the Hough transform to reliably identify line structures within the image. Future more, certain photography techniques (i.e. <a href="http://en.wikipedia.org/wiki/Bokeh">Bokeh</a>) leave portions of images deliberately blurred. Without dividing image into different sub-regions, the classification results would be compromised.</p>
<p>Thus, images are divided into 9 (3&#215;3) sub-images after Canny edge detection, and Hough transform is performed against each sub-images. The figure below illustrates how an image is divided:<br />
<div id="attachment_1267" class="wp-caption aligncenter" style="width: 654px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/3x3.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/3x3.jpg" alt="Image divided into 3x3 sub-images (Microsoft Research Digital Image)" title="Image divided into 3x3 sub-images (Microsoft Research Digital Image)" width="644" height="482" class="size-full wp-image-1267" /></a><p class="wp-caption-text">Image divided into 3x3 sub-images (Microsoft Research Digital Image)</p></div></p>
<p>This technique is especially useful when portions of images are deliberately blurred, like the image shown above. It also helps the line detection accuracy when the image contains complex scenes. By dividing up the image, each sub area&#8217;s complexity is greatly reduced. Other methods in scene separation might achieve even better results, but it is out of the scope for our discussion here.</p>
<p>In my next post, I will show some results obtained from using the method mentioned in this and the previous articles and will also discuss its limitations.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/06/27/image-blur-detection-via-hough-transform-iii/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Image Blur Detection via Hough Transform &#8212; II</title>
		<link>http://www.kerrywong.com/2009/06/24/image-blur-detection-via-hough-transform-ii/</link>
		<comments>http://www.kerrywong.com/2009/06/24/image-blur-detection-via-hough-transform-ii/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 01:44:44 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[Blur Detection]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Edge Detection]]></category>
		<category><![CDATA[Hough Transform]]></category>
		<category><![CDATA[Intel IPP]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1194</guid>
		<description><![CDATA[In my previous post, I briefly discussed the rationale behind automated blur detection in digital imagery and did an overview of an algorithm that could be used to detect blur images. Here I will show some implementation details along with some C++ code snippets.
Experience tells us that blur images tend to contain less details then [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="/2009/06/19/image-blur-detection-via-hough-transform-i/">my previous post</a>, I briefly discussed the rationale behind automated blur detection in digital imagery and did an overview of an algorithm that could be used to detect blur images. Here I will show some implementation details along with some C++ code snippets.<span id="more-1194"></span></p>
<p>Experience tells us that blur images tend to contain less details then their sharper counterparts. And the areas where <a href="http://en.wikipedia.org/wiki/Intensity">intensity</a> transitions occur (e.g. the border of an object) are more well defined in clear images. Mathematically speaking, the <a href="http://en.wikipedia.org/wiki/Slope">slope</a> of the intensity transition is statistically deeper in clear images than blur ones. Since whether an image is blurred or not is not affected by color space, it is sufficient to perform detection in the <a href="http://en.wikipedia.org/wiki/Luminance">luminance</a> space (i.e. gray scale images):</p>
<p>\[I=0.299R\times0.587G\times0.114B\]</p>
<h3>Canny Edge Detection</h3>
<p>Thus the very first step in deciding whether an image or an area within an image is blurred is to use some sort of edge detection algorithms to obtain a collection of the edges in the image.</p>
<p><a href="http://en.wikipedia.org/wiki/Canny_edge_detector">Canny edge detection</a> is a good candidate since it is optimal in terms of good detection and localization. And hysteresis is used to reduce streaking and thus Canny edge detection achieves relatively continuous edge boundaries comparing to other edge detection methods.</p>
<p>In <a href="/2009/05/07/canny-edge-detection-auto-thresholding/">one of my previous posts</a>, I discussed Canny edge detection using auto thresholding utilizing Intel&#8217;s <a href="http://software.intel.com/en-us/intel-ipp/">Integrated Performance Primitives</a> (IPP). I used the same algorithm here for the image pre-processing process.</p>
<h3>Hough Transform</h3>
<p>In order to analyze the gradients along detected edges, it is necessary to first parameterize them. <a href="http://en.wikipedia.org/wiki/Hough_transform">Hough transform</a> comes in handy for this task. </p>
<p>While Hough transform is capable of identifying arbitrary shapes, for the purpose of detecting image blurs simple line detection is more robust. Besides, IPP has an implementation for line detection using Hough transform out of the box.</p>
<p>Since our goal is to determine the quality of the image within a region of interest, we do not need to analyze all the edges identified within that region. But rather, we could select a few based on some pre-determined criteria that would maximize our ability to correctly determine the luminance gradients.</p>
<p>The following code snippet shows my implementation of the edge parameterization method using IPP:</p>
<pre class="brush: cpp;">
    bool CompareIppiPoint(IppiPoint &amp;p1, IppiPoint &amp;p2) {
        if (p1.x == p2.x) {
            return p1.y &lt; p2.y;
        } else {
            return p1.x &lt; p2.x;
        }
    }

    void IPPGrayImage::HoughLine(IppPointPolar delta, int threshold, int maxLineCount, int* pLineCount, IppPointPolar pLines[], list&lt;IppiPoint&gt; pList[]) {
        IppStatus sts;
        IppiSize roiSize = {_width, _height};

        int bufSize;
        sts = ippiHoughLineGetSize_8u_C1R(roiSize, delta, maxLineCount, &amp;bufSize);
        assert(sts == ippStsNoErr);
        Ipp8u * pBuf = ippsMalloc_8u(bufSize);

        Ipp8u *imgBuf;
        int stepSize;
        imgBuf = ippiMalloc_8u_C1(_width, _height, &amp;stepSize);

        sts = ippiConvert_32f8u_C1R(_imgBuffer, _width * PIXEL_SIZE, imgBuf, _width, roiSize, ippRndNear);
        assert(sts == ippStsNoErr);
        assert(imgBuf != NULL);

        sts = ippiHoughLine_8u32f_C1R(imgBuf, _width, roiSize, delta, threshold, pLines, maxLineCount, pLineCount, pBuf);
        assert(sts == ippStsNoErr);

        //d=|x0 * cos a + y0 * sin a - p|
        int val = 0;
        float d;
        for (int x = 0; x &lt; _width; x++) {
            for (int y = 0; y &lt; _height; y++) {
                if (imgBuf[x + y * _width] &gt; 0) {
                    val = imgBuf[x + y * _width];

                    for (int i = 0; i &lt; *pLineCount; i++) {
                        d = abs((float) cos(pLines[i].theta) * (float) x + (float) sin(pLines[i].theta) * (float) y - abs(pLines[i].rho));
                        if (d &lt; threshold) {
                            IppiPoint p;
                            p.x = x;
                            p.y = y;

                            pList[i].push_back(p);
                        }
                    }
                }
            }
        }

        for (int i = 0; i &lt; *pLineCount; i++) {
            pList[i].sort(CompareIppiPoint);
        }

        ippsFree(pBuf);
        ippiFree(imgBuf);
    }
</pre>
<p>Note that the selection for <em>delta</em> is crucial for the line detection quality. In the code above, up to <em>maxLineCount</em> number of lines are detected and each line&#8217;s parameters are stored in <em>pLines[]</em>. The edge image pixel coordinates within a given range that is less than <em>threshold</em> are collected into the list. Because the Hough detection does not indicate the begin and the end point of a line, we need to iterate through the pixels in <em>pList[]</em> and find the sections that the detected lines pass through. The image below illustrates how the edge regions are chosen based on detected line parameters. Image features within a region between the dotted line are recorded based on the distances to the line defined by:<br />
\[d=\vert x_0cos\alpha+y_0sin\alpha-p\vert\]</p>
<div id="attachment_1214" class="wp-caption aligncenter" style="width: 554px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/polar.png"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/polar.png" alt="Region selection for gradient calculation" title="Region selection for gradient calculation" width="544" height="410" class="size-full wp-image-1214" /></a><p class="wp-caption-text">Region selection for gradient calculation</p></div>
<p>In practice, for each parameterized line I chose to select the longest section where the line approximates a section of the edge. Other line sections can be used as well, but the longest portion tends to offer better classification results. The code is shown below, and the thickened section in the figure above illustrates the selected section.</p>
<pre class="brush: cpp;">
    void LineUtils::GetLongestConnectedLinePoints(IppiPoint points[], int len, int threshold, IppiPoint lpoints[], int &amp;maxLen) {
        int maxIndexEnd = 0, curRunLength = 0, maxRunLength = 0;

        lpoints[curRunLength] = points[0];

        for (int i = 1; i &lt; len; i++) {
            if ((abs(points[i].x - lpoints[curRunLength].x) &gt; threshold) || (abs(points[i].y - lpoints[curRunLength].y) &gt; threshold)) {
                if (curRunLength &gt; maxRunLength) {
                    maxRunLength = curRunLength;
                    maxIndexEnd = i;
                }
                curRunLength = 0;
                lpoints[curRunLength] = points[i];
            } else {
                if (curRunLength &gt;= maxLen) {
                    maxRunLength = maxLen;
                    break;
                }

                curRunLength++;
                lpoints[curRunLength] = points[i];
            }
        }

        for (int i = maxIndexEnd - maxRunLength - 1; i &lt; maxIndexEnd; i++) {
            if (i - (maxIndexEnd - maxRunLength) - 1 &lt; maxRunLength) {
                lpoints[i - (maxIndexEnd - maxRunLength - 1)] = points[i];
            }
        }

        maxLen = maxRunLength;
    }
</pre>
<p>In my next post, I will continue with the gradient calculation and some methods to enhance the detection accuracies.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/06/24/image-blur-detection-via-hough-transform-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Image Blur Detection via Hough Transform &#8212; I</title>
		<link>http://www.kerrywong.com/2009/06/19/image-blur-detection-via-hough-transform-i/</link>
		<comments>http://www.kerrywong.com/2009/06/19/image-blur-detection-via-hough-transform-i/#comments</comments>
		<pubDate>Sat, 20 Jun 2009 02:41:13 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[Blur Detection]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Edge Detection]]></category>
		<category><![CDATA[Hough Transform]]></category>
		<category><![CDATA[Intel IPP]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1172</guid>
		<description><![CDATA[It is often necessary to identify and classify images based on their clarities. For instance, it is desirable for an automated process to locate blurred images within a large digitized image library and then automatically sharpen the blurred images via inverse filtering or blind deconvolution. In the following series of articles, I will discuss a [...]]]></description>
			<content:encoded><![CDATA[<p>It is often necessary to identify and classify images based on their clarities. For instance, it is desirable for an automated process to locate blurred images within a large digitized image library and then automatically sharpen the blurred images via inverse filtering or blind deconvolution. In the following series of articles, I will discuss a practical method in detecting blur images using <a href="http://en.wikipedia.org/wiki/Hough_transform">Hough Transform</a>.<span id="more-1172"></span></p>
<h3>Background</h3>
<p>Image blur is typically caused by</p>
<ul>
<li>Motion (e.g. the relative movement between the camera and the object during exposure)</li>
<li>Out-of-focus</li>
<li>Low lighting condition</li>
</ul>
<p>Other types of image blur may also occur in photography (such as <a href="http://en.wikipedia.org/wiki/Bokeh">Bokeh</a>). And it is desirable to be able to automatically distinguish desired image blur (e.g. Bokeh caused by camera lens with a shallow depth of field) from un-intended blur (e.g. out of focus).</p>
<p>When reference images (e.g. a series of images with different focus settings) are present, detecting image blur is a relatively simple task. For instance, in passive auto-focus cameras, a series of scene images are captured with progressive focus settings. And the intensity differences are calculated within the same region across these different images. Thus, the image with the highest intensity difference corresponds to the correct focus setting. In Active-focus cameras, image blur detection problem is circumvented by measuring the distance between the lens and the object.</p>
<p>The problem becomes more difficult if we are only given a single image. Since many parameters that we used above in camera auto-focusing are not present in a single image setting, we could not reliably infer image sharpness by the method used in passive auto-focusing as we do not have sufficient knowledge to re-construct the series of images necessary for comparison.</p>
<p>We can however, tell whether an image is in-focus by calculating the intensity differences along the edges in an image. If the calculated intensity is higher than a predefined threshold, we deduce that the image is sharp. And if the calculated intensity is lower than a predefined threshold, we conclude that the image is blurred. So now we shifted the problem to identifying such optimal regions where the intensities are calculated.</p>
<h3>Algorithm Overview</h3>
<p>In this algorithm, we first use <a href="http://en.wikipedia.org/wiki/Canny_edge_detector">Canny edge detection</a> to obtain the edges in the image. The edges are then parameterized using Hough transform. We then calculate the pixel gradients along the parameterized lines detected and finally we use the gradients to decide whether the image is blurred.</p>
<p>I will discuss some technical and implementation details in the up-coming posts. Stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/06/19/image-blur-detection-via-hough-transform-i/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
