<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://www.developer.nokia.com/Community/Wiki/skins/common/feed.css?1917"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;feed=atom&amp;action=history</id>
		<title>Real-time edge detection in camera viewport - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;feed=atom&amp;action=history"/>
		<link rel="alternate" type="text/html" href="http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;action=history"/>
		<updated>2013-05-19T05:59:59Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.18.6</generator>

	<entry>
		<id>http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=183170&amp;oldid=prev</id>
		<title>Hamishwillee: Hamishwillee - Change to use new video player which works with Lumia 920 and other mobile browsers</title>
		<link rel="alternate" type="text/html" href="http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=183170&amp;oldid=prev"/>
				<updated>2013-01-30T04:58:42Z</updated>
		
		<summary type="html">&lt;p&gt;Hamishwillee - Change to use new video player which works with Lumia 920 and other mobile browsers&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
		&lt;tr valign='top'&gt;
		&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Older revision&lt;/td&gt;
		&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 04:58, 30 January 2013&lt;/td&gt;
		&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 168:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 168:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;And here are videos of this application in action. On Nokia N950:&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;And here are videos of this application in action. On Nokia N950:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;{{#ev&lt;/del&gt;:youtube&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;|&lt;/del&gt;C3x4OqaBiMY&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;}}&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;mediaplayer&amp;gt;http&lt;/ins&gt;:&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;//www.&lt;/ins&gt;youtube&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;.com/watch?v=&lt;/ins&gt;C3x4OqaBiMY&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/mediaplayer&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;On Nokia N8:&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;On Nokia N8:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;{{#ev&lt;/del&gt;:youtube&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;|&lt;/del&gt;ZaZrnS7fG7I&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;}}&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;mediaplayer&amp;gt;http&lt;/ins&gt;:&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;//www.&lt;/ins&gt;youtube&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;.com/watch?v=&lt;/ins&gt;ZaZrnS7fG7I&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/mediaplayer&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Nokia N950 screencast to show details that are not visible in filmed videos:&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Nokia N950 screencast to show details that are not visible in filmed videos:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;{{#ev&lt;/del&gt;:youtube&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;|&lt;/del&gt;5FvNBoh1VEQ&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;}}&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;mediaplayer&amp;gt;http&lt;/ins&gt;:&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;//www.&lt;/ins&gt;youtube&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;.com/watch?v=&lt;/ins&gt;5FvNBoh1VEQ&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/mediaplayer&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;== Summary ==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;== Summary ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;In this article I have demonstrated how to optimise algorithm (that uses complex calculations) for real-time image processing and displaying from camera.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;In this article I have demonstrated how to optimise algorithm (that uses complex calculations) for real-time image processing and displaying from camera.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Hamishwillee</name></author>	</entry>

	<entry>
		<id>http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=175186&amp;oldid=prev</id>
		<title>Hamishwillee: Text replace - &quot;&lt;code cpp&gt;&quot; to &quot;&lt;code cpp-qt&gt;&quot;</title>
		<link rel="alternate" type="text/html" href="http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=175186&amp;oldid=prev"/>
				<updated>2012-10-11T01:18:33Z</updated>
		
		<summary type="html">&lt;p&gt;Text replace - &amp;quot;&amp;lt;code cpp&amp;gt;&amp;quot; to &amp;quot;&amp;lt;code cpp-qt&amp;gt;&amp;quot;&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
		&lt;tr valign='top'&gt;
		&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Older revision&lt;/td&gt;
		&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 01:18, 11 October 2012&lt;/td&gt;
		&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 42:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 42:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Below is an implementation of an edge detection algorithm ([http://en.wikipedia.org/wiki/Sobel_operator Sobel operator]) for RGB image. The implementation has purposefully been written to be inefficient so we can demonstrate how it can be improved.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Below is an implementation of an edge detection algorithm ([http://en.wikipedia.org/wiki/Sobel_operator Sobel operator]) for RGB image. The implementation has purposefully been written to be inefficient so we can demonstrate how it can be improved.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;code cpp&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;code cpp&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;-qt&lt;/ins&gt;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;function calcLuma(QRgb val)&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;function calcLuma(QRgb val)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 85:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 85:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;The first problem is that we shouldn't use {{Icode|pixel()}} and {{Icode|setPixel()}} functions. They are inefficient because multiplication is used to calculate position of pixel - internally it most probably look like this: {{Icode|y * bytes_per_line + x * bytes_per_pixel}}. It is much better to use {{Icode|bits()}} and {{Icode|scanLine()}} functions to get position of all image or position of line in memory respectively. In this case we will use {{Icode|bits()}} function to get position of first line and will get address of next line by adding {{Icode|bytesPerLine()}} to previous line (notice that we are iterating over {{Icode|lines(y)}} in our algorithm). This way we can replace {{Icode|image.pixel(x,y)}} functions with something like this:&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;The first problem is that we shouldn't use {{Icode|pixel()}} and {{Icode|setPixel()}} functions. They are inefficient because multiplication is used to calculate position of pixel - internally it most probably look like this: {{Icode|y * bytes_per_line + x * bytes_per_pixel}}. It is much better to use {{Icode|bits()}} and {{Icode|scanLine()}} functions to get position of all image or position of line in memory respectively. In this case we will use {{Icode|bits()}} function to get position of first line and will get address of next line by adding {{Icode|bytesPerLine()}} to previous line (notice that we are iterating over {{Icode|lines(y)}} in our algorithm). This way we can replace {{Icode|image.pixel(x,y)}} functions with something like this:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;code cpp&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;code cpp&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;-qt&lt;/ins&gt;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;uchar* lineAddress = image.bits();&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;uchar* lineAddress = image.bits();&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;....&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;....&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 111:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 111:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;The last thing to solve is square root calculation - it is really expensive operation. Again we can optimize by precalculating values here: sqrt(x*x+y*y) will always be more than 255 when x or y is more than 255. In such case we need to create table of size 256x256 and precalculate square roots. Try using sqrt ({{Icode|qSqrt()}} function) instead of precalculated values and you will notice that view is lagging from about 0.5 to 2 seconds (depends on your phone's CPU). Here is MeeGo Harmattan implementation for precalculating square roots and using them:&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;The last thing to solve is square root calculation - it is really expensive operation. Again we can optimize by precalculating values here: sqrt(x*x+y*y) will always be more than 255 when x or y is more than 255. In such case we need to create table of size 256x256 and precalculate square roots. Try using sqrt ({{Icode|qSqrt()}} function) instead of precalculated values and you will notice that view is lagging from about 0.5 to 2 seconds (depends on your phone's CPU). Here is MeeGo Harmattan implementation for precalculating square roots and using them:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;code cpp&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;code cpp&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;-qt&lt;/ins&gt;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; &amp;#160; for (int y = 0; y &amp;lt; 255; y++)&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; &amp;#160; for (int y = 0; y &amp;lt; 255; y++)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; &amp;#160; &amp;#160; &amp;#160; for (int x = 0; x &amp;lt; y; x++)&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; &amp;#160; &amp;#160; &amp;#160; for (int x = 0; x &amp;lt; y; x++)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Hamishwillee</name></author>	</entry>

	<entry>
		<id>http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=152160&amp;oldid=prev</id>
		<title>Hamishwillee: Text replace - &quot;Category:MeeGo&quot; to &quot;Category:MeeGo Harmattan&quot;</title>
		<link rel="alternate" type="text/html" href="http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=152160&amp;oldid=prev"/>
				<updated>2012-06-13T10:57:52Z</updated>
		
		<summary type="html">&lt;p&gt;Text replace - &amp;quot;&lt;a href=&quot;/Community/Wiki/Category:MeeGo&quot; class=&quot;mw-redirect&quot; title=&quot;Category:MeeGo&quot;&gt;Category:MeeGo&lt;/a&gt;&amp;quot; to &amp;quot;&lt;a href=&quot;/Community/Wiki/Category:MeeGo_Harmattan&quot; title=&quot;Category:MeeGo Harmattan&quot;&gt;Category:MeeGo Harmattan&lt;/a&gt;&amp;quot;&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
		&lt;tr valign='top'&gt;
		&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Older revision&lt;/td&gt;
		&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 10:57, 13 June 2012&lt;/td&gt;
		&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Category:Qt]][[Category:Multimedia]][[Category:Symbian]][[Category:MeeGo]][[Category:Code Examples]][[Category:Optimization]][[Category:Graphics]][[Category:Imaging]][[Category:Camera]][[Category:Symbian^3]][[Category:Symbian Anna]][[Category:Nokia Belle]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Category:Qt]][[Category:Multimedia]][[Category:Symbian]][[Category:MeeGo &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Harmattan&lt;/ins&gt;]][[Category:Code Examples]][[Category:Optimization]][[Category:Graphics]][[Category:Imaging]][[Category:Camera]][[Category:Symbian^3]][[Category:Symbian Anna]][[Category:Nokia Belle]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{FeaturedArticle|timestamp=20120527}}&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{FeaturedArticle|timestamp=20120527}}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{Abstract|This article explains how to optimise an image edge detection algorithm so that it can be used for &amp;quot;real-time&amp;quot; previewing of video in the camera's viewport. }}&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{Abstract|This article explains how to optimise an image edge detection algorithm so that it can be used for &amp;quot;real-time&amp;quot; previewing of video in the camera's viewport. }}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Hamishwillee</name></author>	</entry>

	<entry>
		<id>http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=150077&amp;oldid=prev</id>
		<title>Kiran10182: Kiran10182 - FA template added</title>
		<link rel="alternate" type="text/html" href="http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=150077&amp;oldid=prev"/>
				<updated>2012-05-27T08:50:51Z</updated>
		
		<summary type="html">&lt;p&gt;Kiran10182 - FA template added&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
		&lt;tr valign='top'&gt;
		&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Older revision&lt;/td&gt;
		&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 08:50, 27 May 2012&lt;/td&gt;
		&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Category:Qt]][[Category:Multimedia]][[Category:Symbian]][[Category:MeeGo]][[Category:Code Examples]][[Category:Optimization]][[Category:Graphics]][[Category:Imaging]][[Category:Camera]][[Category:Symbian^3]][[Category:Symbian Anna]][[Category:Nokia Belle]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Category:Qt]][[Category:Multimedia]][[Category:Symbian]][[Category:MeeGo]][[Category:Code Examples]][[Category:Optimization]][[Category:Graphics]][[Category:Imaging]][[Category:Camera]][[Category:Symbian^3]][[Category:Symbian Anna]][[Category:Nokia Belle]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;{{FeaturedArticle|timestamp=20120527}}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{Abstract|This article explains how to optimise an image edge detection algorithm so that it can be used for &amp;quot;real-time&amp;quot; previewing of video in the camera's viewport. }}&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{Abstract|This article explains how to optimise an image edge detection algorithm so that it can be used for &amp;quot;real-time&amp;quot; previewing of video in the camera's viewport. }}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Kiran10182</name></author>	</entry>

	<entry>
		<id>http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=149664&amp;oldid=prev</id>
		<title>Hamishwillee: Hamishwillee - fix typo</title>
		<link rel="alternate" type="text/html" href="http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=149664&amp;oldid=prev"/>
				<updated>2012-05-17T06:29:35Z</updated>
		
		<summary type="html">&lt;p&gt;Hamishwillee - fix typo&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
		&lt;tr valign='top'&gt;
		&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Older revision&lt;/td&gt;
		&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 06:29, 17 May 2012&lt;/td&gt;
		&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 90:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 90:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/code&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/code&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;This code will pass 4 bytes to {{Icode|calcLuma()}} function from position (x-1, y-1) because {{Icode|-bytes_per_line &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;= &lt;/del&gt;y-1. x}} must be multiplied by 4 because we are working with RGB data and each pixel takes 4 bytes. Again since we are iterating over x as well instead of multiplying by 4 we can calculate next x value by adding 4 (again 4 bytes per pixel) to it. Basically if we want to eliminate using {{Icode|pixel()}} and {{Icode|setPixel()}} functions from our code we should work with image data directly.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;This code will pass 4 bytes to {{Icode|calcLuma()}} function from position (x-1, y-1) because {{Icode|-bytes_per_line &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt; &amp;amp;#61; &lt;/ins&gt;y-1. x}} must be multiplied by 4 because we are working with RGB data and each pixel takes 4 bytes. Again since we are iterating over x as well instead of multiplying by 4 we can calculate next x value by adding 4 (again 4 bytes per pixel) to it. Basically if we want to eliminate using {{Icode|pixel()}} and {{Icode|setPixel()}} functions from our code we should work with image data directly.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;The next inefficient thing in our code is that we are recalculating same luma (brightness) values much more times than necessary. E.g. we are calculating luma for point (3, 3) when we are calculating gradient magnitude for all 8 points around this point). Solution to this is to calculate luma points only for 3 lines that are currently relevant to us for first line. For subsequent lines we only have to calculate next line. E.g.: let's say we are working in line 1 and already know luma points for line 0, 1 and 2:&amp;#160; &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;The next inefficient thing in our code is that we are recalculating same luma (brightness) values much more times than necessary. E.g. we are calculating luma for point (3, 3) when we are calculating gradient magnitude for all 8 points around this point). Solution to this is to calculate luma points only for 3 lines that are currently relevant to us for first line. For subsequent lines we only have to calculate next line. E.g.: let's say we are working in line 1 and already know luma points for line 0, 1 and 2:&amp;#160; &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Hamishwillee</name></author>	</entry>

	<entry>
		<id>http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=149663&amp;oldid=prev</id>
		<title>Hamishwillee: Hamishwillee - Minor subedit</title>
		<link rel="alternate" type="text/html" href="http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=149663&amp;oldid=prev"/>
				<updated>2012-05-17T06:27:11Z</updated>
		
		<summary type="html">&lt;p&gt;Hamishwillee - Minor subedit&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
		&lt;tr valign='top'&gt;
		&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Older revision&lt;/td&gt;
		&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 06:27, 17 May 2012&lt;/td&gt;
		&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Category:Qt]][[Category:Multimedia]][[Category:Symbian]][[Category:MeeGo]][[Category:Code Examples]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Category:Qt]][[Category:Multimedia]][[Category:Symbian]][[Category:MeeGo]][[Category:Code Examples&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;]][[Category:Optimization]][[Category:Graphics]][[Category:Imaging]][[Category:Camera]][[Category:Symbian^3]][[Category:Symbian Anna]][[Category:Nokia Belle&lt;/ins&gt;]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{Abstract|This article explains how to &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;detect edges in &lt;/del&gt;real-time &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;and display result &lt;/del&gt;in camera's viewport. }}&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{Abstract|This article explains how to &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;optimise an image edge detection algorithm so that it can be used for &amp;quot;&lt;/ins&gt;real-time&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;&amp;quot; previewing of video &lt;/ins&gt;in &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;the &lt;/ins&gt;camera's viewport. }}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{Note|This is an entry in the [[PureView Imaging Competition 2012Q2]]}}&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{Note|This is an entry in the [[PureView Imaging Competition 2012Q2]]}}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 29:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 29:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;== Introduction ==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;== Introduction ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;It is quite easy &lt;/del&gt;to &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;write &lt;/del&gt;image editing &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;algorithms using Qt and you can write Instragram like application quite fast &lt;/del&gt;(see &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;here &lt;/del&gt;[[Image editing techniques and algorithms using Qt]] for &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;some samples&lt;/del&gt;). &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;Now if you try to use the very &lt;/del&gt;same algorithms &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;in &lt;/del&gt;real-time (&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;while displaying in viewport) you will notice that view &lt;/del&gt;in camera's viewport &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;is displayed with some delay (e.g. moving object will be displayed only after some seconds&lt;/del&gt;). &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;Here I will try to explain &lt;/del&gt;how to optimize edge detection algorithm for &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;performance and &lt;/del&gt;you will be able to apply same techniques for other algorithms.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Image editing algorithms that take several seconds &lt;/ins&gt;to &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;complete are acceptable for Instagram-like static &lt;/ins&gt;image editing&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;, where quality is more important than speed &lt;/ins&gt;(see [[Image editing techniques and algorithms using Qt]] for &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;examples&lt;/ins&gt;). &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;However these &lt;/ins&gt;same algorithms &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;are not suitable for &lt;/ins&gt;real-time &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;usage &lt;/ins&gt;(&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;e.g. display &lt;/ins&gt;in &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;the &lt;/ins&gt;camera's viewport) &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;as they would result in visibly poor frame rates&lt;/ins&gt;. &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;This article explains &lt;/ins&gt;how to optimize &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;an &lt;/ins&gt;edge detection algorithm for &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;calculation speed (possibly sacrificing some level of &amp;quot;quality&amp;quot;) so that it can be applied to a video feed in real-time. The hope is that &lt;/ins&gt;you will be able to apply same techniques for &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;optimising &lt;/ins&gt;other algorithms.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;== Camera viewport technical details ==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;== Camera viewport technical details ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Before starting to work let's overview how we should handle Camera in Qt in order to manipulate viewport. For this task we will need to use &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;[http://doc.qt.nokia.com/qtmobility/qabstractvideosurface.html &lt;/del&gt;QAbstractVideoSurface&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;]&lt;/del&gt;. You have to subclass this class and implement some specific methods. In present() method you get frame data that you can convert to image (QImage class) and draw where you want to using painter (QPainter class). Please note that &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;where &lt;/del&gt;is problem in Meego with frame data &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;and it &lt;/del&gt;is covered in [[MeeGo Camera VideoSurface manipulation]] (we will return to MeeGo in this article as well).&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Before starting to work let's overview how we should handle Camera in Qt in order to manipulate viewport. For this task we will need to use &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Qapiname|&lt;/ins&gt;QAbstractVideoSurface&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;}}&lt;/ins&gt;. You have to subclass this class and implement some specific methods. In &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Icode|&lt;/ins&gt;present()&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;}} &lt;/ins&gt;method you get frame data that you can convert to image (&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Qapiname|&lt;/ins&gt;QImage&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;}} &lt;/ins&gt;class) and draw where you want to using painter (&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Qapiname|&lt;/ins&gt;QPainter&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;}} &lt;/ins&gt;class). Please note that &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;there &lt;/ins&gt;is &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;a &lt;/ins&gt;problem in Meego with frame data&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;; this &lt;/ins&gt;is covered in [[MeeGo Camera VideoSurface manipulation]] (we will return to MeeGo in this article as well).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;== Edge detection optimization ==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;== Edge detection optimization ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;Let's say here &lt;/del&gt;is &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;our &lt;/del&gt;edge detection algorithm ([http://en.wikipedia.org/wiki/Sobel_operator Sobel operator]) for RGB image &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;(&lt;/del&gt;written &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;on purpose &lt;/del&gt;to be &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;completely &lt;/del&gt;inefficient&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;):&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Below &lt;/ins&gt;is &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;an implementation of an &lt;/ins&gt;edge detection algorithm ([http://en.wikipedia.org/wiki/Sobel_operator Sobel operator]) for RGB image&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;. The implementation has purposefully been &lt;/ins&gt;written to be inefficient &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;so we can demonstrate how it can be improved.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;code cpp&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;code cpp&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 80:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 82:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;This code will work but it is really slow and inefficient. So let's see what we could do better.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;This code will work but it is really slow and inefficient. So let's see what we could do better.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;At &lt;/del&gt;first we shouldn't use pixel() and setPixel() functions. They are inefficient because multiplication is used to calculate position of pixel - internally it most probably look like this: y * bytes_per_line + x * bytes_per_pixel. It is much better to use bits() and scanLine() functions to get position of all image or position of line in memory respectively. In this case we will use bits() function to get position of first line and will get address of next line by adding bytesPerLine() to previous line (notice that we are iterating over lines(y) in our algorithm). This way we can replace image.pixel(x,y) functions with something like this:&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;The &lt;/ins&gt;first &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;problem is that &lt;/ins&gt;we shouldn't use &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Icode|&lt;/ins&gt;pixel()&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;}} &lt;/ins&gt;and &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Icode|&lt;/ins&gt;setPixel()&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;}} &lt;/ins&gt;functions. They are inefficient because multiplication is used to calculate position of pixel - internally it most probably look like this: &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Icode|&lt;/ins&gt;y * bytes_per_line + x * bytes_per_pixel&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;}}&lt;/ins&gt;. It is much better to use &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Icode|&lt;/ins&gt;bits()&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;}} &lt;/ins&gt;and &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Icode|&lt;/ins&gt;scanLine()&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;}} &lt;/ins&gt;functions to get position of all image or position of line in memory respectively. In this case we will use &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Icode|&lt;/ins&gt;bits()&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;}} &lt;/ins&gt;function to get position of first line and will get address of next line by adding &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Icode|&lt;/ins&gt;bytesPerLine()&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;}} &lt;/ins&gt;to previous line (notice that we are iterating over &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Icode|&lt;/ins&gt;lines(y)&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;}} &lt;/ins&gt;in our algorithm). This way we can replace &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Icode|&lt;/ins&gt;image.pixel(x,y)&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;}} &lt;/ins&gt;functions with something like this:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;code&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;code &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;cpp&lt;/ins&gt;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;uchar* lineAddress = image.bits();&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;uchar* lineAddress = image.bits();&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;....&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;....&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 88:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 90:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/code&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/code&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;This code will pass 4 bytes to calcLuma function from position (x-1, y-1) because -bytes_per_line = y-1. x must be multiplied by 4 because we are working with RGB data and each pixel takes 4 bytes. Again since we are iterating over x as well instead of multiplying by 4 we can calculate next x value by adding 4 (again 4 bytes per pixel) to it. Basically if we want to eliminate using pixel() and setPixel() functions from our code we should work with image data directly.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;This code will pass 4 bytes to &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Icode|&lt;/ins&gt;calcLuma&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;()}} &lt;/ins&gt;function from position (x-1, y-1) because &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Icode|&lt;/ins&gt;-bytes_per_line = y-1. x&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;}} &lt;/ins&gt;must be multiplied by 4 because we are working with RGB data and each pixel takes 4 bytes. Again since we are iterating over x as well instead of multiplying by 4 we can calculate next x value by adding 4 (again 4 bytes per pixel) to it. Basically if we want to eliminate using &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Icode|&lt;/ins&gt;pixel()&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;}} &lt;/ins&gt;and &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Icode|&lt;/ins&gt;setPixel()&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;}} &lt;/ins&gt;functions from our code we should work with image data directly.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;Next &lt;/del&gt;inefficient thing in our code is that we are recalculating same luma (brightness) values much more times than necessary. E.g. we are calculating luma for point (3, 3) when we are calculating gradient magnitude for all 8 points around this point). Solution to this is to calculate luma points only for 3 lines that are currently relevant to us for first line. For subsequent lines we only have to calculate next line. E.g.: let's say we are working in line 1 and already know luma points for line 0, 1 and 2:&amp;#160; &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;The next &lt;/ins&gt;inefficient thing in our code is that we are recalculating same luma (brightness) values much more times than necessary. E.g. we are calculating luma for point (3, 3) when we are calculating gradient magnitude for all 8 points around this point). Solution to this is to calculate luma points only for 3 lines that are currently relevant to us for first line. For subsequent lines we only have to calculate next line. E.g.: let's say we are working in line 1 and already know luma points for line 0, 1 and 2:&amp;#160; &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;code&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;code &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;text&lt;/ins&gt;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;0 . . . . . &amp;lt;- known luma points&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;0 . . . . . &amp;lt;- known luma points&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;1 . . . . . &amp;lt;- known luma points&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;1 . . . . . &amp;lt;- known luma points&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 106:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 108:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Note: In MeeGo Harmattan we have image data with luma already and it is much more efficient to use that data directly. In code sample that is attached to this article luma data is used directly in MeeGo Harmattan case.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Note: In MeeGo Harmattan we have image data with luma already and it is much more efficient to use that data directly. In code sample that is attached to this article luma data is used directly in MeeGo Harmattan case.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;The last thing to solve is square root calculation - it is really expensive operation. Again we can optimize by precalculating values here: sqrt(x*x+y*y) will always be more than 255 when x or y is more than 255. In such case we need to create table of size 256x256 and precalculate square roots. Try using sqrt (qSqrt() function) instead of precalculated values and you will notice that view is lagging from about 0.5 to 2 seconds (depends on your phone's CPU). Here is MeeGo Harmattan implementation for precalculating square roots and using them:&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;The last thing to solve is square root calculation - it is really expensive operation. Again we can optimize by precalculating values here: sqrt(x*x+y*y) will always be more than 255 when x or y is more than 255. In such case we need to create table of size 256x256 and precalculate square roots. Try using sqrt (&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;{{Icode|&lt;/ins&gt;qSqrt()&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;}} &lt;/ins&gt;function) instead of precalculated values and you will notice that view is lagging from about 0.5 to 2 seconds (depends on your phone's CPU). Here is MeeGo Harmattan implementation for precalculating square roots and using them:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;code cpp&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;code cpp&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key wiki:diff:version:1.11a:oldid:149639:newid:149663 --&gt;
&lt;/table&gt;</summary>
		<author><name>Hamishwillee</name></author>	</entry>

	<entry>
		<id>http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=149639&amp;oldid=prev</id>
		<title>Chintandave er: Chintandave er - moved note for pureview contest on top</title>
		<link rel="alternate" type="text/html" href="http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=149639&amp;oldid=prev"/>
				<updated>2012-05-16T19:34:22Z</updated>
		
		<summary type="html">&lt;p&gt;Chintandave er - moved note for pureview contest on top&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
		&lt;tr valign='top'&gt;
		&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Older revision&lt;/td&gt;
		&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 19:34, 16 May 2012&lt;/td&gt;
		&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Category:Qt]][[Category:Multimedia]][[Category:Symbian]][[Category:MeeGo]][[Category:Code Examples]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Category:Qt]][[Category:Multimedia]][[Category:Symbian]][[Category:MeeGo]][[Category:Code Examples]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{Abstract|This article explains how to detect edges in real-time and display result in camera's viewport. }}&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{Abstract|This article explains how to detect edges in real-time and display result in camera's viewport. }}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;{{Note|This is an entry in the [[PureView Imaging Competition 2012Q2]]}}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{ArticleMetaData &amp;lt;!-- v1.2 --&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{ArticleMetaData &amp;lt;!-- v1.2 --&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 177:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 179:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;== Summary ==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;== Summary ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;In this article I have demonstrated how to optimise algorithm (that uses complex calculations) for real-time image processing and displaying from camera. &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;In this article I have demonstrated how to optimise algorithm (that uses complex calculations) for real-time image processing and displaying from camera.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;{{Note|This is an entry in the [[PureView Imaging Competition 2012Q2]]}}&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key wiki:diff:version:1.11a:oldid:149540:newid:149639 --&gt;
&lt;/table&gt;</summary>
		<author><name>Chintandave er</name></author>	</entry>

	<entry>
		<id>http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=149540&amp;oldid=prev</id>
		<title>Hamishwillee: Hamishwillee - Bot update - Fix metadata etc</title>
		<link rel="alternate" type="text/html" href="http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=149540&amp;oldid=prev"/>
				<updated>2012-05-16T04:06:35Z</updated>
		
		<summary type="html">&lt;p&gt;Hamishwillee - Bot update - Fix metadata etc&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
		&lt;tr valign='top'&gt;
		&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Older revision&lt;/td&gt;
		&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 04:06, 16 May 2012&lt;/td&gt;
		&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 9:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 9:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|platform= Symbian^3 and later, Meego&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|platform= Symbian^3 and later, Meego&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|devicecompatability= All Symbian^3 and later, All Meego&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|devicecompatability= All Symbian^3 and later, All Meego&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|dependencies= &amp;lt;!-- Any other/external dependencies e.g.: Google Maps Api v1.0 --&amp;gt; &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|dependencies= &amp;lt;!-- Any other/external dependencies e.g.: Google Maps Api v1.0 --&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|signing=Self-Signed&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|signing= Self-Signed&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|capabilities= UserEnvironment&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|capabilities= UserEnvironment&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|keywords= QCamera, QAbstractVideoSurface&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|keywords= QCamera, QAbstractVideoSurface&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|language= &amp;lt;!-- Language category code for non-English topics - e.g. Lang-Chinese --&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|language= &amp;lt;!-- Language category code for non-English topics - e.g. Lang-Chinese --&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|translated-by= &amp;lt;!-- [[User:XXXX]] --&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|translated-by= &amp;lt;!-- [[User:XXXX]] --&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|translated-from-title= &amp;lt;!-- Title only --&amp;gt; &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|translated-from-title= &amp;lt;!-- Title only --&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|translated-from-id= &amp;lt;!-- Id of translated revision --&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|translated-from-id= &amp;lt;!-- Id of translated revision --&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|review-by=&amp;lt;!-- After re-review: [[User:username]] --&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|review-by= &amp;lt;!-- After re-review: [[User:username]] --&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|review-timestamp= &amp;lt;!-- After re-review: YYYYMMDD --&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|review-timestamp= &amp;lt;!-- After re-review: YYYYMMDD --&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|update-by= &amp;lt;!-- After significant update: [[User:username]]--&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|update-by= &amp;lt;!-- After significant update: [[User:username]]--&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|update-timestamp= &amp;lt;!-- After significant update: YYYYMMDD --&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|update-timestamp= &amp;lt;!-- After significant update: YYYYMMDD --&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|creationdate= 20120512&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|creationdate= 20120512&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|author=[[User:daliusd]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|author= [[User:daliusd]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;}}&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;}}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 55:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 55:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; &amp;#160; int lxm1ym0 = calcLuma(image.pixel(x-1, y&amp;#160; ));&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; &amp;#160; int lxm1ym0 = calcLuma(image.pixel(x-1, y&amp;#160; ));&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; &amp;#160; int lxm1yp1 = calcLuma(image.pixel(x-1, y+1));&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; &amp;#160; int lxm1yp1 = calcLuma(image.pixel(x-1, y+1));&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; &amp;#160; int lxm0ym1 = calcLuma(image.pixel(x &lt;del class=&quot;diffchange diffchange-inline&quot;&gt; &lt;/del&gt;, y-1));&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; &amp;#160; int lxm0ym1 = calcLuma(image.pixel(x, y-1));&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; &amp;#160; int lxm0yp1 = calcLuma(image.pixel(x &lt;del class=&quot;diffchange diffchange-inline&quot;&gt; &lt;/del&gt;, y+1));&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; &amp;#160; int lxm0yp1 = calcLuma(image.pixel(x, y+1));&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; &amp;#160; int lxp1ym1 = calcLuma(image.pixel(x+1, y-1));&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; &amp;#160; int lxp1ym1 = calcLuma(image.pixel(x+1, y-1));&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; &amp;#160; int lxp1ym0 = calcLuma(image.pixel(x+1, y-1));&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; &amp;#160; int lxp1ym0 = calcLuma(image.pixel(x+1, y-1));&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Hamishwillee</name></author>	</entry>

	<entry>
		<id>http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=149314&amp;oldid=prev</id>
		<title>Daliusd: Daliusd - /* Summary */</title>
		<link rel="alternate" type="text/html" href="http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=149314&amp;oldid=prev"/>
				<updated>2012-05-12T19:58:05Z</updated>
		
		<summary type="html">&lt;p&gt;Daliusd - &lt;span class=&quot;autocomment&quot;&gt;- Summary&lt;/span&gt;&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
		&lt;tr valign='top'&gt;
		&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Older revision&lt;/td&gt;
		&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 19:58, 12 May 2012&lt;/td&gt;
		&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 177:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 177:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;== Summary ==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;== Summary ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;In this article I have demonstrated how to &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;optimize &lt;/del&gt;algorithm that uses complex calculations for real-time image processing and displaying from camera. &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;In this article I have demonstrated how to &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;optimise &lt;/ins&gt;algorithm &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;(&lt;/ins&gt;that uses complex calculations&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;) &lt;/ins&gt;for real-time image processing and displaying from camera. &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{Note|This is an entry in the [[PureView Imaging Competition 2012Q2]]}}&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{Note|This is an entry in the [[PureView Imaging Competition 2012Q2]]}}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key wiki:diff:version:1.11a:oldid:149311:newid:149314 --&gt;
&lt;/table&gt;</summary>
		<author><name>Daliusd</name></author>	</entry>

	<entry>
		<id>http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=149311&amp;oldid=prev</id>
		<title>Daliusd: Daliusd -</title>
		<link rel="alternate" type="text/html" href="http://www.developer.nokia.com/Community/Wiki/index.php?title=Real-time_edge_detection_in_camera_viewport&amp;diff=149311&amp;oldid=prev"/>
				<updated>2012-05-12T19:45:16Z</updated>
		
		<summary type="html">&lt;p&gt;Daliusd -&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;[[Category:Qt]][[Category:Multimedia]][[Category:Symbian]][[Category:MeeGo]][[Category:Code Examples]]&lt;br /&gt;
{{Abstract|This article explains how to detect edges in real-time and display result in camera's viewport. }}&lt;br /&gt;
&lt;br /&gt;
{{ArticleMetaData &amp;lt;!-- v1.2 --&amp;gt;&lt;br /&gt;
|sourcecode= [[Media:Camera edge 2.zip]]&lt;br /&gt;
|installfile= &amp;lt;!-- Link to installation file (e.g. [[Media:The Installation File.sis]]) --&amp;gt;&lt;br /&gt;
|devices= Nokia N8, Nokia N950&lt;br /&gt;
|sdk= Qt SDK 1.2.1&lt;br /&gt;
|platform= Symbian^3 and later, Meego&lt;br /&gt;
|devicecompatability= All Symbian^3 and later, All Meego&lt;br /&gt;
|dependencies= &amp;lt;!-- Any other/external dependencies e.g.: Google Maps Api v1.0 --&amp;gt; &lt;br /&gt;
|signing=Self-Signed&lt;br /&gt;
|capabilities= UserEnvironment&lt;br /&gt;
|keywords= QCamera, QAbstractVideoSurface&lt;br /&gt;
|language= &amp;lt;!-- Language category code for non-English topics - e.g. Lang-Chinese --&amp;gt;&lt;br /&gt;
|translated-by= &amp;lt;!-- [[User:XXXX]] --&amp;gt;&lt;br /&gt;
|translated-from-title= &amp;lt;!-- Title only --&amp;gt; &lt;br /&gt;
|translated-from-id= &amp;lt;!-- Id of translated revision --&amp;gt;&lt;br /&gt;
|review-by=&amp;lt;!-- After re-review: [[User:username]] --&amp;gt;&lt;br /&gt;
|review-timestamp= &amp;lt;!-- After re-review: YYYYMMDD --&amp;gt;&lt;br /&gt;
|update-by= &amp;lt;!-- After significant update: [[User:username]]--&amp;gt;&lt;br /&gt;
|update-timestamp= &amp;lt;!-- After significant update: YYYYMMDD --&amp;gt;&lt;br /&gt;
|creationdate= 20120512&lt;br /&gt;
|author=[[User:daliusd]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
It is quite easy to write image editing algorithms using Qt and you can write Instragram like application quite fast (see here [[Image editing techniques and algorithms using Qt]] for some samples). Now if you try to use the very same algorithms in real-time (while displaying in viewport) you will notice that view in camera's viewport is displayed with some delay (e.g. moving object will be displayed only after some seconds). Here I will try to explain how to optimize edge detection algorithm for performance and you will be able to apply same techniques for other algorithms.&lt;br /&gt;
&lt;br /&gt;
== Camera viewport technical details ==&lt;br /&gt;
&lt;br /&gt;
Before starting to work let's overview how we should handle Camera in Qt in order to manipulate viewport. For this task we will need to use [http://doc.qt.nokia.com/qtmobility/qabstractvideosurface.html QAbstractVideoSurface]. You have to subclass this class and implement some specific methods. In present() method you get frame data that you can convert to image (QImage class) and draw where you want to using painter (QPainter class). Please note that where is problem in Meego with frame data and it is covered in [[MeeGo Camera VideoSurface manipulation]] (we will return to MeeGo in this article as well).&lt;br /&gt;
&lt;br /&gt;
== Edge detection optimization ==&lt;br /&gt;
&lt;br /&gt;
Let's say here is our edge detection algorithm ([http://en.wikipedia.org/wiki/Sobel_operator Sobel operator]) for RGB image (written on purpose to be completely inefficient):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp&amp;gt;&lt;br /&gt;
function calcLuma(QRgb val)&lt;br /&gt;
{&lt;br /&gt;
    int luma = (int)(0.2126 * (val &amp;gt;&amp;gt; 16 &amp;amp; 0xff) + 0.7152 * (val &amp;gt;&amp;gt; 8 &amp;amp; 0xff) + (0.0722 * (val &amp;amp; 0xff)));&lt;br /&gt;
    return luma&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
QImage newImage = QImage(image.width(), image.height(), QImage::Format_RGB32)&lt;br /&gt;
&lt;br /&gt;
for (int y = 1; y &amp;lt; image.height()-1; y++)&lt;br /&gt;
    for (int x = 1; x &amp;lt; image.width()-1; x++)&lt;br /&gt;
    {&lt;br /&gt;
    // calculate luma (brightness) for points around this one&lt;br /&gt;
    int lxm1ym1 = calcLuma(image.pixel(x-1, y-1));&lt;br /&gt;
    int lxm1ym0 = calcLuma(image.pixel(x-1, y  ));&lt;br /&gt;
    int lxm1yp1 = calcLuma(image.pixel(x-1, y+1));&lt;br /&gt;
    int lxm0ym1 = calcLuma(image.pixel(x  , y-1));&lt;br /&gt;
    int lxm0yp1 = calcLuma(image.pixel(x  , y+1));&lt;br /&gt;
    int lxp1ym1 = calcLuma(image.pixel(x+1, y-1));&lt;br /&gt;
    int lxp1ym0 = calcLuma(image.pixel(x+1, y-1));&lt;br /&gt;
    int lxp1yp1 = calcLuma(image.pixel(x+1, y-1));&lt;br /&gt;
&lt;br /&gt;
    // calculate gradients&lt;br /&gt;
    int dx = - lxm1ym1 - lxm1ym0 * 2 - lxm1yp1 + lxp1ym1 + lxp1ym0 * 2 + lxp1yp1;&lt;br /&gt;
    int dy = - lxm1ym1 - lxm0ym1 * 2 - lxp1ym1 + lxm1yp1 + lxp0ym1 * 2 + lxp1yp1;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    // calculate gradient magnitude&lt;br /&gt;
    int mag = qSqrt(dx*dx+dy*dy);&lt;br /&gt;
    if (mag &amp;gt; 255)&lt;br /&gt;
        mag = 255;&lt;br /&gt;
&lt;br /&gt;
    // set pixel&lt;br /&gt;
    newImage.setPixel(x, y, mag + mag &amp;lt;&amp;lt; 8 + mag &amp;lt;&amp;lt; 16);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code will work but it is really slow and inefficient. So let's see what we could do better.&lt;br /&gt;
&lt;br /&gt;
At first we shouldn't use pixel() and setPixel() functions. They are inefficient because multiplication is used to calculate position of pixel - internally it most probably look like this: y * bytes_per_line + x * bytes_per_pixel. It is much better to use bits() and scanLine() functions to get position of all image or position of line in memory respectively. In this case we will use bits() function to get position of first line and will get address of next line by adding bytesPerLine() to previous line (notice that we are iterating over lines(y) in our algorithm). This way we can replace image.pixel(x,y) functions with something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
uchar* lineAddress = image.bits();&lt;br /&gt;
....&lt;br /&gt;
int lxm1ym1 = calcLuma((int)*(lineAddress - bytes_per_line + (x-1) * 4));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code will pass 4 bytes to calcLuma function from position (x-1, y-1) because -bytes_per_line = y-1. x must be multiplied by 4 because we are working with RGB data and each pixel takes 4 bytes. Again since we are iterating over x as well instead of multiplying by 4 we can calculate next x value by adding 4 (again 4 bytes per pixel) to it. Basically if we want to eliminate using pixel() and setPixel() functions from our code we should work with image data directly.&lt;br /&gt;
&lt;br /&gt;
Next inefficient thing in our code is that we are recalculating same luma (brightness) values much more times than necessary. E.g. we are calculating luma for point (3, 3) when we are calculating gradient magnitude for all 8 points around this point). Solution to this is to calculate luma points only for 3 lines that are currently relevant to us for first line. For subsequent lines we only have to calculate next line. E.g.: let's say we are working in line 1 and already know luma points for line 0, 1 and 2:  &lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
0 . . . . . &amp;lt;- known luma points&lt;br /&gt;
1 . . . . . &amp;lt;- known luma points&lt;br /&gt;
2 . . . . . &amp;lt;- known luma points&lt;br /&gt;
3 . . . . . &amp;lt;- unknown luma points&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now when we need to calculate gradient magnitudes for points in line 2 we just reuse luma points from lines 1 and 2 and only have to calculate luma points in line 3.&lt;br /&gt;
&lt;br /&gt;
Here we can make another optimization with memory as well (we should save memory usage in mobile devices if we can and if it doesn't hurt performance). Since we are calculating luma points for lines around current line it is actually safe to write on top of current image. This way we don't need to create new image in memory and will save about 1Mb of memory.&lt;br /&gt;
&lt;br /&gt;
Next thing to optimize is luma calculation formula: Y = 0.2126 * R + 0.7152 * G + 0.0722 * B. First problem with this formula is that it uses real numbers and real numbers arithmetics is slower on computers than integer arithmetics. Therefore we change our formula in this way: Y = (0.2126 * 256 * R + 0.7152 * 256 * G + 0.0722 * 256 * B) / 256 = (54 * R + 183 * G + 18 * B) &amp;gt;&amp;gt; 8 - shift operation is faster than division operation on binary CPU what are majorities of CPUs nowadays and we now have formula that deals with integer numbers. And we can optimise this even more: R, G and B values are from range 0 to 255 therefore we can precalculate multiplication operations into arrays and our formula will be simple as (lumaR[R] + lumaG[G] + lumaB[B]) &amp;gt;&amp;gt; 8.&lt;br /&gt;
&lt;br /&gt;
Note: In MeeGo Harmattan we have image data with luma already and it is much more efficient to use that data directly. In code sample that is attached to this article luma data is used directly in MeeGo Harmattan case.&lt;br /&gt;
&lt;br /&gt;
The last thing to solve is square root calculation - it is really expensive operation. Again we can optimize by precalculating values here: sqrt(x*x+y*y) will always be more than 255 when x or y is more than 255. In such case we need to create table of size 256x256 and precalculate square roots. Try using sqrt (qSqrt() function) instead of precalculated values and you will notice that view is lagging from about 0.5 to 2 seconds (depends on your phone's CPU). Here is MeeGo Harmattan implementation for precalculating square roots and using them:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp&amp;gt;&lt;br /&gt;
    for (int y = 0; y &amp;lt; 255; y++)&lt;br /&gt;
        for (int x = 0; x &amp;lt; y; x++)&lt;br /&gt;
            {&lt;br /&gt;
            int val = (int)qSqrt(x*x+y*y);&lt;br /&gt;
            val = val &amp;gt; 255 ? 255 : val;&lt;br /&gt;
            sqrt_table[x][y] = val;&lt;br /&gt;
            sqrt_table[y][x] = val;&lt;br /&gt;
            }&lt;br /&gt;
    ....&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    unsigned char *dst = m_bits + m_width * 4;&lt;br /&gt;
    const unsigned char *src = source.bits() + m_width * 2;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    for (int y = 1; y &amp;lt; m_height-1; ++y) {&lt;br /&gt;
        unsigned char *d_x = dst + 4;&lt;br /&gt;
        const unsigned char *s_x = src + 2 + 1;&lt;br /&gt;
        dst = dst + m_width * 4; // four bytes per pixel&lt;br /&gt;
        src = src + m_width * 2; // two bytes per pixel&lt;br /&gt;
&lt;br /&gt;
        for (int x = 1; x &amp;lt; m_width-1; ++x)&lt;br /&gt;
        {&lt;br /&gt;
            int gx = qAbs(-(*(s_x-m_width*2-2)) - *(s_x-2)*2 - *(s_x+m_width*2-2) + *(s_x-m_width*2+2) + *(s_x+2)*2 + *(s_x+m_width*2+2));&lt;br /&gt;
            int gy = qAbs(-(*(s_x-m_width*2-2)) - *(s_x-m_width*2)*2 - *(s_x-m_width*2-2) + *(s_x+m_width*2-2) + *(s_x+m_width*2)*2 + *(s_x+m_width*2+2));&lt;br /&gt;
&lt;br /&gt;
            int g;&lt;br /&gt;
            // Try using this instead of sqrt_table to see performance penalty&lt;br /&gt;
            // g = (int)qSqrt(gx*gx+gy*gy);&lt;br /&gt;
            // g = (g &amp;gt; 255 ? 255 : g);&lt;br /&gt;
&lt;br /&gt;
            if (gx &amp;gt; 255 || gy &amp;gt; 255)&lt;br /&gt;
                g = 255;&lt;br /&gt;
            else&lt;br /&gt;
                g = sqrt_table[gx][gy];&lt;br /&gt;
&lt;br /&gt;
            *d_x = g;&lt;br /&gt;
            *(d_x+1) = g;&lt;br /&gt;
            *(d_x+2) = g;&lt;br /&gt;
            *(d_x+3) = 0;&lt;br /&gt;
&lt;br /&gt;
            d_x+=4;&lt;br /&gt;
            s_x+=2;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's actually it: we have eliminated square root extraction and all multiplication operations from our algorithm and it now can be used in real-time. Download sample application from here to see complete algorithm: [[Media:Camera edge 2.zip]]&lt;br /&gt;
&lt;br /&gt;
Here is what you might see using this app:&lt;br /&gt;
&lt;br /&gt;
[[File:View edge.png]]&lt;br /&gt;
&lt;br /&gt;
And here are videos of this application in action. On Nokia N950:&lt;br /&gt;
&lt;br /&gt;
{{#ev:youtube|C3x4OqaBiMY}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On Nokia N8:&lt;br /&gt;
&lt;br /&gt;
{{#ev:youtube|ZaZrnS7fG7I}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nokia N950 screencast to show details that are not visible in filmed videos:&lt;br /&gt;
&lt;br /&gt;
{{#ev:youtube|5FvNBoh1VEQ}}&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
In this article I have demonstrated how to optimize algorithm that uses complex calculations for real-time image processing and displaying from camera. &lt;br /&gt;
&lt;br /&gt;
{{Note|This is an entry in the [[PureView Imaging Competition 2012Q2]]}}&lt;/div&gt;</summary>
		<author><name>Daliusd</name></author>	</entry>

	</feed>