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

<channel>
	<title>Computer Vision Software</title>
	<atom:link href="http://www.computer-vision-software.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.computer-vision-software.com/blog</link>
	<description>Rhonda Ltd., computer vision software blog</description>
	<lastBuildDate>Wed, 01 Jun 2022 02:55:39 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Face recognition</title>
		<link>http://www.computer-vision-software.com/blog/2022/06/face-recognition-2/</link>
					<comments>http://www.computer-vision-software.com/blog/2022/06/face-recognition-2/#respond</comments>
		
		<dc:creator><![CDATA[rhondasw]]></dc:creator>
		<pubDate>Wed, 01 Jun 2022 02:24:35 +0000</pubDate>
				<category><![CDATA[Demo]]></category>
		<category><![CDATA[Demo video]]></category>
		<category><![CDATA[Demo videos]]></category>
		<category><![CDATA[Face recognition]]></category>
		<category><![CDATA[YouTube]]></category>
		<category><![CDATA[Machine learning]]></category>
		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=301</guid>

					<description><![CDATA[The face recognition demo shows person facial feature training via a single photo and subsequent face matching on the live video stream, using VisionLabs’ library integrated onto the H22 System on a Module (SoM). The H22 SoM, designed in-house, is a power-efficient camera platform for high-resolution video encoding and live video streaming. The core of [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>The face recognition demo shows person facial feature training via a single photo and subsequent face matching on the live video stream, using VisionLabs’ library integrated onto the <strong>H22 System on a Module</strong> (SoM).</p>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="Ambarella H22 SoC-based| Face Recognition Demo" width="500" height="281" src="https://www.youtube.com/embed/k7v8mfbmtxo?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<span id="more-301"></span>



<p>The H22 SoM, designed in-house, is a power-efficient camera platform for high-resolution video encoding and live video streaming. The core of the SoM platform is an Ambarella H22S85N<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" /> System on a Chip that integrates an advanced image processing pipeline, H.265 (HEVC) and H.264 (AVC) encoders , and a powerful Quad core ARM® Cortex<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />-A53 CPU for advanced business logic like computer vision, flight control, WiFi streaming, and other user applications. The H22 SoM is supplied with the <em>SoM SDK</em> – a Linux-based toolchain that allows executing user-level applications on the ARM core. To speed up the development process, there are a series of reference code samples for the SoM SDK.</p>



<p>The demo system implements a face training scenario using a simple
mobile app. A single photo, captured through a mobile phone and added to the
database, is quite enough for the NN to learn. Photos with name tags stored in
the mobile app are transferred via WiFi onto the SoM to extract face
descriptors and carry on with the recognition scenario. Recognition occurs in
real-time on faces detected in the camera’s field of view. The markup is straightforward:
red
frames and “Unknown” tags
for the people that are not found in the database, green frames and a nametag
for the people from the database, and grey frames without a tag for the stage
when the person’s face is found but is still being processed by the recognition
algorithm.</p>



<p>This basic face
detection and tracking algorithm was put together for demo purposes. More
robust solutions are to be selected for more practical usage scenarios. One such
solution will be in an upcoming post.</p>



<p>Despite being only a demo implementation, the high resolution and decent image quality enables precise face detection and recognition with indoor lighting in overcrowded conditions. Face recognition capabilities could be a value-added feature for security applications such as seamless entry control. </p>
]]></content:encoded>
					
					<wfw:commentRss>http://www.computer-vision-software.com/blog/2022/06/face-recognition-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Pose Estimation and Activity recognition demo</title>
		<link>http://www.computer-vision-software.com/blog/2022/04/pose-estimation-and-activity-recognition-demo/</link>
					<comments>http://www.computer-vision-software.com/blog/2022/04/pose-estimation-and-activity-recognition-demo/#respond</comments>
		
		<dc:creator><![CDATA[rhondasw]]></dc:creator>
		<pubDate>Fri, 22 Apr 2022 03:27:15 +0000</pubDate>
				<category><![CDATA[Demo]]></category>
		<category><![CDATA[Demo video]]></category>
		<category><![CDATA[Demo videos]]></category>
		<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[YouTube]]></category>
		<category><![CDATA[Object Recognition]]></category>
		<category><![CDATA[Object Tracking]]></category>
		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=294</guid>

					<description><![CDATA[This demo showcases real-time Human Pose Estimation, based on the Open Pose library, ported onto the camera platform, and designed by Rhonda’s Activity Recognition neural network for human behavior recognition. The two Deep Learning Neural Networks (DNN), along with the video pipeline, run on the Rhonda Software CV22 System on a Module (CV22 SoM). CV22 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="Ambarella CV22 SoC-based Activity Recognition Demo" width="500" height="281" src="https://www.youtube.com/embed/nVAGCLpMNGk?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>This demo showcases real-time Human Pose Estimation, based
on the Open Pose library, ported onto the camera platform, and designed by
Rhonda’s Activity Recognition neural network for human behavior recognition.
The two Deep Learning Neural Networks (DNN),
along with the video pipeline, run on the Rhonda Software CV22 System on a Module
(CV22 SoM).</p>



<span id="more-294"></span>



<p>CV22 SoM &#8211; designed in-house
as a low-power camera platform, is capable of running multiple neural
networks, in addition to providing superior image quality. The core of the SoM platform is an Ambarella CV22 System
on a Chip – an ARM-based Image Signal Processor with a DNN inference
acceleration engine, implemented on a single crystal.</p>



<p>Both CV applications run simultaneously. The <em>Pose Estimation</em> network performs human body
detection in a full 4K frame, and people’s figures recognized in the camera’s field
of view are visualized with “skeleton-like” pose markups. A blob of pixels
around a foreground skeleton selected within the region of interest is passed
to the <em>Activity recognition DNN</em>. </p>



<p>The activity recognition algorithm is a simple, yet robust
demo built by Rhonda’s CV team from scratch, and trained to identify several activity
types: walking, standing, welcome hand gestures (high-five), jumping jacks,
body-weight squats. Recognized Activity for the foreground body is displayed in
the upper- left corner of the screen.</p>



<p>After the initial port onto the CV22 platform, Open Pose
algorithm delivered a frame rate of 1 frame per second. It took a number of optimization
procedures performed by Rhonda’s CV experts (such as pruning, quantization, and
dedicated retraining) to achieve a fifteen fold acceleration in performance.</p>



<p>The system can be trained for different use cases, such as
security, elderly care, production automation, sports activity analysis, and
more.</p>



<p>For demo and testing purposes we&#8217;ve deployed a setup with HDMI video injection to show platforms&#8217; recognition capabilities with additional activities. </p>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="Ambarella CV22 SoC-based Activity Recognition Demo with Injected Video Signal on the Camera Edge" width="500" height="281" src="https://www.youtube.com/embed/Gd7Ymw_d85c?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>As a road-safety application example, Rhonda Software has assembled
the <em>Pedestrian detection</em> demo, based
on the same optimized port of the Open Pose library. The algorithm is applied
to automotive conditions to detect pedestrians as participants of road traffic.</p>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Ambarella CV22 SoC-based Pedestrian Detection Demo" width="500" height="281" src="https://www.youtube.com/embed/5C4vQ-MIT2E?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>http://www.computer-vision-software.com/blog/2022/04/pose-estimation-and-activity-recognition-demo/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Character Generator for Lattice HDR-60 FPGA Board</title>
		<link>http://www.computer-vision-software.com/blog/2013/02/character-generator-for-lattice-hdr-60-fpga-board/</link>
					<comments>http://www.computer-vision-software.com/blog/2013/02/character-generator-for-lattice-hdr-60-fpga-board/#comments</comments>
		
		<dc:creator><![CDATA[Yuri Vashchenko]]></dc:creator>
		<pubDate>Fri, 08 Feb 2013 00:48:00 +0000</pubDate>
				<category><![CDATA[FPGA]]></category>
		<category><![CDATA[HW]]></category>
		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=185</guid>

					<description><![CDATA[Introduction Rhonda software specializes in developing video analytic algorithms, including hardware development for FPGA. Lattice HDR-60 Evaluation board was selected as a development platform. A typical development cycle consists of implementing all required modules in VHDL or Verilog programming language and then debugging them in a simulator. When debugging of individual components is complete, they [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><span style="font-size: 2em;">Introduction</span></p>
<p style="text-align: justify;">Rhonda software specializes in developing video analytic algorithms, including hardware development for FPGA. Lattice HDR-60 Evaluation board was selected as a development platform. A typical development cycle consists of implementing all required modules in VHDL or Verilog programming language and then debugging them in a simulator. When debugging of individual components is complete, they are integrated and tested on actual FPGA hardware. If something is not working as it should, debugging the hardware video analytics algorithms on the actual hardware can be a challenge, especially if no soft-core CPU is instantiated. HDR-60 board has a camera sensor (input) and an HDMI output. So, many video analytic algorithms take input video signal from the camera, process it and send resulted output video stream to HDMI. If something is not working and the results you see are not what you expected, you have very limited means of debugging.</p>
<p style="text-align: justify;"><span id="more-185"></span></p>
<p style="text-align: justify;">One of such means is the Reveal Analyzer. It can “record” values of different signals on predefined triggers and it is possible to see and analyze the results later. Although Reveal analyzer is a very useful tool but it also has some limitations. First, the learning curve is steep, and you need to spend a lot of time before it can record and show you the values of signals you wanted. Moreover, the more signals you are interested in, the more on-chip memory it is required to store these values. Finally, Reveal analyzer modifies design, uses extra resources and you need to rebuild the whole design every time some changes in monitored signals are made. For complex designs there could be not enough space or memory left on chip. Moreover, rebuilding the design could take hours.</p>
<p style="text-align: justify;">Besides Reveal analyzer, there is a programmable led light on EBR-60 that can be turned on or off. It is helpful, but it is only 1 bit of information and it is very difficult to output a number to that led.</p>
<p style="text-align: justify;">To make hardware debugging easier we designed a character generator. Using it, a developer can “print” on the HDMI output any numerical/text messages.</p>
<p style="text-align: justify;">Ability to print text and other data is useful not only for debugging purposes – output of data and messages like current system time, system uptime, number of processed objects, etc. improves usability of designs created for FPGA board.</p>
<p style="text-align: justify;">Data from the camera sensor, after passing the imaging pipeline (that may include sensor controller, debayer and tonemapper modules) arrives in the form of 8 bits (for grayscale) or 24 bits (for color video) per pixel. In addition, sensor provides 2 control signals, <i>lva</i>l (line valid, “1” for valid pixels in line or “0” for blanks between lines) and <i>fval</i> (frame valid, “1” for valid frame lines or “0” for blank lines). When <i>fval</i> = ‘1’ and <i>lval </i>= ‘1’ the pixel is valid and will be displayed on the screen. Pixel data, fval and lval change every clock tick. The frequency of pixel clock depends on sensor configuration. Default settings produce frequency of 74.25 MHz. HDR-60 sensor supports resolution of 1280&#215;720 at 60 frames per second (60 Hz).</p>
<p style="text-align: justify;">We want our character generator to print characters on top of the image from camera (overlay mode).</p>
<p style="text-align: justify;">A straightforward method of character output could be as follows:</p>
<ol>
<li>Copy original frame into a frame buffer</li>
<li>For each character in the output text string:
<ol>
<li>Extract corresponding font matrix from font ROM (graphical representation of this character)</li>
<li>For each pixel in font matrix:
<ol>
<li>calculate corresponding screen coordinates and address in frame buffer</li>
<li>if pixel is visible replace it in the frame buffer with text color, otherwise leave it “as is”.</li>
</ol>
</li>
</ol>
</li>
<li>Send contents of modified frame buffer to video output</li>
</ol>
<p style="text-align: justify;">However sometimes we do not have a frame buffer in the design (for example, there is not enough memory for it). In such cases characters should be printed in a streaming (online) mode, i.e. module always deals with the only current pixel for which it decides if current pixel should go to output “as is” or it should be replaced with a text color.</p>
<p style="text-align: justify;">The following two pictures illustrate both approaches of printing characters. The first approach (with a frame buffer) is more suitable for software implementation. The second (online) approach is well-suited for the FPGA hardware design, and it was implemented. Both examples show the process of printing of the same number (1234). In both cases the printing is in progress.</p>
<p style="text-align: justify;">Each square cell represents a single pixel from the camera sensor. Blue pixels are outside the printed text area – they go to output as is. Green pixels belong to the printed character; their original brightness/color has been replaced with text color. Gray pixels belong to the printed text area, but don’t belong to character font matrix, so their brightness has been decreased according to transparency setting to provide greater contrast between printed text and background image to make it more readable. Finally, white pixels are not yet processed. They are here to illustrate the intermediate state of the process.</p>
<p><a href="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture1.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-191" alt="frame_buffer_cg" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture1.png" width="796" height="470" srcset="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture1.png 796w, http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture1-300x177.png 300w" sizes="auto, (max-width: 796px) 100vw, 796px" /></a></p>
<p style="text-align: justify;">Picture1. Frame buffer implementation.<br />
In the traditional software implementation example, digits “1” and “2” (with corresponding transparency setting) have already been printed and printing digit “3” is in progress.</p>
<p><a href="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture2.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-192" alt="pipelined_cg" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture2.png" width="792" height="469" srcset="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture2.png 792w, http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture2-300x177.png 300w" sizes="auto, (max-width: 792px) 100vw, 792px" /></a></p>
<p>Picture 2. Streaming (online) implementation.</p>
<p style="text-align: justify;">In this example upper part of the whole number 1234 is complete, and lower part will be complete when corresponding input pixels from sensor are processed.</p>
<h1>Binary 8-bit digitizer</h1>
<p style="text-align: justify;">The very first attempt to implement a character generator was a binary digitizer. It was very simple and was able to display 8-bit integers at the specified screen position in binary format. A developer had to manually interpret the output, e.g. a decimal number “157” was printed as “10011101”. Below are some technical implementation details:</p>
<ul>
<li>Pixel counter knows when every line starts and ends (using line valid (<i>lval</i>) sensor signal) and counts line pixels (<i>X</i> screen coordinate)</li>
<li>Line counter knows when each frame and each line starts and ends (using the same line valid (lval) and frame valid (<i>fval</i>) sensor signals) and counts frame lines (<i>Y</i> screen coordinate).</li>
<li>Knowing text window size and offset, algorithm decides, if current pixel belongs to any of 8 printed bits and, if yes, finds out the value of the corresponding bit (“0” or “1”).</li>
<li>Then, checking the pixel coordinates (<i>x</i> and <i>y</i>), algorithm finds out if it belongs to the edge of the character position (8&#215;16 pixels).</li>
<li>If “0” is to be printed and current pixel belongs to any character edge, its brightness/color is replaced with text color. Otherwise, if “1” is to be printed and current pixel belongs to right character edge its brightness/color is also replaced with text color. If both conditions are not true, pixel goes to output as is.</li>
</ul>
<p style="text-align: justify;">The module was resided in one .vhdl entity. The advantage of this implementation was its simplicity. The disadvantages were:</p>
<ul>
<li>Binary output (only “0”s and “1”s). It was not very convenient to use</li>
<li>8 bit limitation. To print 10-bit number it was required to instantiate module twice which would eat twice as many resources.</li>
</ul>
<h1>7-Segment hex number printer</h1>
<h2>One-digit printer</h2>
<p style="text-align: justify;">The idea of 7-segment hex printer is to implement character generator that could output hex digits like most cheap LCD displays in portable electronic devices work.</p>
<p> <a href="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture3.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-193" alt="7segment" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture3.png" width="397" height="132" srcset="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture3.png 397w, http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture3-300x99.png 300w" sizes="auto, (max-width: 397px) 100vw, 397px" /></a></p>
<p><a href="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture4.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-186" alt="segments" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture4.png" width="314" height="441" srcset="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture4.png 314w, http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture4-213x300.png 213w" sizes="auto, (max-width: 314px) 100vw, 314px" /></a></p>
<p style="text-align: justify;">Every hex digit (<b>0-9</b>, <b>a-f</b>) is encoded into 7-bit bitmask B[0..6], where each bit controls corresponding segment. For example, as shown in the picture above, digit “8” should light all segments, so it’s bitmask is “1111111” (0x7f).</p>
<p style="text-align: justify;">First implementation was able to output a single hex digit for given 4-bit number. The algorithm is explained in details below:</p>
<ol>
<li>Screen coordinates (<i>Xs, Ys</i>), <i>0 ≤ Xs &lt; ScreenWidth, 0 ≤ Ys &lt; ScreenHeigh</i>t of current input pixel are used to find out if it belongs to a character area (8&#215;16 pixels). If no, pixel goes to output as is</li>
<li>If input pixel belongs to character position, local coordinates inside the character are calculated <i>(Xc, Yc), 0 ≤ Xc &lt; 8, 0 ≤ Yc &lt; 16.</i></li>
<li>Character local coordinates are used to find out if pixel belongs to any segment or not. If it does not, it’s brightness decreased according to transparency setting.</li>
<li>If pixel belongs to a segment, its character coordinates <i>Xc</i> and <i>Yc</i> are used to get segment id <i>S, 0 ≤ S &lt; 6.</i></li>
<li>Segment <i>S</i> is then used as an index to get “0” or “1” from input digit’s bitmask <i>B.</i> If it’s “1”, the brightness of the pixel increased, otherwise it’s decreased according to transparency setting.</li>
<li>Resulting pixel goes to HDMI output.</li>
</ol>
<h2>Multiple-digits printer</h2>
<p style="text-align: justify;">Having one-digit hex character generator would make it possible to print any hex digit anywhere on the screen. It would be better than just binary output, but, especially when design occupies almost the whole chip, it could lead to ineffective resources (LUTs) usage &#8211; to print 32-bit integer, it would require to instantiate the hex digit printer 8 times (for each hex digit). Moreover, logic that computes segments was mostly combinational, so, in addition to extra space usage, every extra instance would negatively affect maximum design frequency (FMAX).</p>
<p style="text-align: justify;">So, the next step was to improve hex printer to make it print hex numbers of specified width with the single instance of the printer entity.</p>
<p style="text-align: justify;">To implement this, we designed a serializer module. Serializer takes n-bit input binary integer and index value and returns corresponding 4-bit digit. For example, for the given 11-bit input number “110’1011’1000” (0x6B8) serializer will return “0110” (0x6) for input index “0”, “1011” (0xB) for index “1” and “1000” (0x8) for index “2”.</p>
<p style="text-align: justify;">One-digit printer used provided coordinates to print a digit at the specified location. Multiple-digits printer uses the provided location to print first digit and calculates corresponding coordinates for remaining digits.</p>
<p style="text-align: justify;">As Picture 2 above illustrates, frame pixels arrive pixel by pixel, line by line. Multiple-digits printer module prints the input number accordingly, i.e. when pixels from first frame line arrive, the module modifies them to print first line of the whole number (not just first digit). When first image line ends, top line of all printed digits is ready. Then the second line is processed pixel by pixel, then the third, etc., until all lines are processed.</p>
<h1>7-segment decimal printer</h1>
<p style="text-align: justify;">Although hex printer that can print any number is much better than previous binary 8-bit printer, it still not very convenient to use because it outputs numbers in hex format, while people got used to see decimal numbers. To make life easier, the Decimal printer module was designed. It uses hex printer described above, but before going there, input number is converted to the corresponding BCD representation.</p>
<p> <a href="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture5.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-187" alt="binary_to_bcd" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture5.png" width="493" height="201" srcset="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture5.png 493w, http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture5-300x122.png 300w" sizes="auto, (max-width: 493px) 100vw, 493px" /></a></p>
<h2>Binary to BCD converter</h2>
<p style="text-align: justify;">Binary to BCD converter converts binary numbers into corresponding packed Binary-Coded Decimal (BCD) representation. For example, number 0x0A would be converted to 0x10 and number 0xFF would become 0x255. The module uses efficient [<a href="http://en.wikipedia.org/wiki/Double_dabble">Double dabble</a>] algorithm.</p>
<p style="text-align: justify;">Original version of <a href="http://en.wikipedia.org/wiki/Double_dabble">algorithm</a> is combinational, meaning that result of conversion is ready almost immediately. Unfortunately, for long binary inputs (e.g. 32-bit integers) it produces a lot of combinational logic which occupies significant amount of chip and dramatically decreases maximum frequency at which the design can work (FMAX). Considering the fact that during normal operation we don’t need converted BCD representation at the same clock as input binary number arrives, the algorithm was implemented in a sequential way to save FPGA area space and improve timing, produce less combinational logic and (FMAX).</p>
<p style="text-align: justify;">Resulting algorithm is not pipelined and for <i>n</i>-bit input integer it produces <i>m</i>-bit output BCD representation in <i>k</i> clock cycles, here <i>m = RoundUp(n / 3) * 4</i> and <i>k = n * RoundUp(n / 3)</i>.</p>
<p style="text-align: justify;">The Binary to BCD converter module does nothing with segments, fonts and/or pixels and can be instantiated in any context where converting from binary representation to corresponding BCD one is required and specified earlier latency is acceptable. The original (fully combinational) algorithm and description how it works can be found <a href="http://en.wikipedia.org/wiki/Double_dabble">here</a>. The modified version is more complex and employs a finite state machine to process each bit of input number in a sequential manner. You can download the source code of modified version <a href="http://www.computer-vision-software.com/files/bin2bcd.zip">here</a>.</p>
<h1>Character printer</h1>
<h2>Transparency setting</h2>
<p style="text-align: justify;">Next step was to implement a Character printer to be able to print anything including numbers, text or both. As you can see in the picture below, there are 3 main cases:</p>
<ul>
<li>A pixel does not belong to the output text window. In this case it goes to output as is. These are the pixels around the printed text.</li>
<li>A pixel is inside of the output text window, but it does not belong to a character. In this case pixel brightness is altered according to the transparency setting, to make the text more readable on different backgrounds. Transparency can be turned off (in this case green letters on the green background will not be seen), or set to “no background”, when all pixels around the text will be black.</li>
</ul>
<p><a href="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture6.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-188" alt="cg_text_example" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture6.png" width="666" height="87" srcset="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture6.png 666w, http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture6-300x39.png 300w" sizes="auto, (max-width: 666px) 100vw, 666px" /></a></p>
<h2>Character Generator</h2>
<p style="text-align: justify;">            Functional block diagram of Character printer is presented below:</p>
<p><a href="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture7.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-189" alt="cg_functional_diagram" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture7.png" width="625" height="497" srcset="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture7.png 625w, http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture7-300x238.png 300w" sizes="auto, (max-width: 625px) 100vw, 625px" /></a></p>
<p>Picture 3. Functional Block Diagram of Character printer module.</p>
<p><a href="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture8.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-190" alt="cg_sequence" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture8.png" width="624" height="353" srcset="http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture8.png 624w, http://www.computer-vision-software.com/blog/wp-content/uploads/2013/02/picture8-300x169.png 300w" sizes="auto, (max-width: 624px) 100vw, 624px" /></a></p>
<p>Picture 4. Sequence diagram of Character printer module.</p>
<p style="text-align: justify;">Character generator is a main module where almost all work is done. Character generator works as follows:</p>
<ul>
<li>Pixel counter uses line valid signal to understand when a new line starts and counts line pixels (on-screen <i>Xs</i> coordinate), <i>0 ≤ Xs &lt; ScreenWidth</i>;</li>
<li>Line counter uses frame valid and line valid signals to understand when a new frame and new line start and counts lines on the current frame (on-screen <i>Ys</i> coordinate), <i>0 ≤ Ys &lt; ScreenHeight</i>.</li>
<li>Character printer uses the font size parameter, which is a scale factor from 0 to 4. Characters at scale 0 are 8&#215;16 pixels large, scale 1 gives 16&#215;32, scale 2 gives 32&#215;64 pixels, etc. Using current on-screen coordinates (<i>Xs, Ys</i>) character generator calculates text coordinates (<i>Xt, Yt</i>), <i>0 ≤ Xt &lt; TextColumns, 0 ≤ Yt &lt; TextRows..</i></li>
<li>Text coordinates are fed to position converter which generates indices for string serializer (explained in details below) to get the character code that should be printed at current position.</li>
<li>Character generator also converts screen coordinates to local character coordinates (<i>Xc, Yc</i>), <i>0 ≤ Xc &lt; 8, 0 ≤ Yc &lt; 16.</i></li>
<li>Local-character coordinates <i>Xc</i> and <i>Yc</i>, input character from string serializer (with data valid signal) are then fed to Font ROM module.</li>
<li>Font ROM, based on given data (local character coordinates (<i>Xc, Yc</i>), character ASCII code and character valid), returns “1” when pixel at the given position belongs to a printed character, “0” otherwise.</li>
<li>If a pixel is outside the printed text window, it goes to output as is. Otherwise, if it does not belong to a printed character, it is altered to decrease its brightness according to transparency parameter. If it belongs to a printed character, it’s replaced with text color setting.</li>
</ul>
<h3>Position converter</h3>
<p style="text-align: justify;">The main task of the position converter is to convert on-screen text coordinates (<i>Xt,</i> <i>Yt</i>) into text coordinates (indices) inside the text window (<i>Xw</i>, <i>Yw</i>), that go to String serializer module to get corresponding character from the video memory. Position converter is a very simple module made of combinational logic only.</p>
<h2>Serializer</h2>
<h3>String serializer</h3>
<p style="text-align: justify;">String serializer contains video memory (RAM or ROM) and returns a character for requested position (<i>Xw, Yw</i>). If position is out of window range, it de-asserts data valid signal. In a simple text-only implementation with no placeholders for numbers, string serializer works similar to the serializer module from hex printer, but instead of returning fixed number of bits by input index, it returns character ASCII code requested by index.</p>
<h3>Number serializer</h3>
<p style="text-align: justify;">In more complex design, message ROM would contain special placeholders for digits of one or more displayed numbers, like “<i>%d</i>” in C-language “<i>printf</i>()” function. In this case, there would be one more module instantiated, number serializer or “str”. Main function of “str” is similar to serializer module from hex printer, which used input index to extract requested 4-bit digit from longer (n-bit) input binary integer, but instead of returning binary 4-bit digit, “str” returns corresponding 8-bit ASCII code of this digit. Following the example from hex printer module, for the given 11-bit input number “110’0111’1000” (0x678) str will return 0x36 (ASCII code of character “6”) for input index “0”, 0x37 (ASCII code of character “7”) for index “1” and 0x38 (ASCII code of character “8”) for index “2”.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://www.computer-vision-software.com/blog/2013/02/character-generator-for-lattice-hdr-60-fpga-board/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>FPGA implementation of myAudience-Count. Overview and details.</title>
		<link>http://www.computer-vision-software.com/blog/2012/12/fpga-implementation-of-myaudience-count-overview-and-details/</link>
					<comments>http://www.computer-vision-software.com/blog/2012/12/fpga-implementation-of-myaudience-count-overview-and-details/#respond</comments>
		
		<dc:creator><![CDATA[Sergey Koulik]]></dc:creator>
		<pubDate>Fri, 21 Dec 2012 06:17:39 +0000</pubDate>
				<category><![CDATA[FPGA]]></category>
		<category><![CDATA[Background Model]]></category>
		<category><![CDATA[HW]]></category>
		<category><![CDATA[Motion]]></category>
		<category><![CDATA[myAudience-Count]]></category>
		<category><![CDATA[Optical Flow]]></category>
		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=175</guid>

					<description><![CDATA[Recently, Rhonda Software took yet another step towards more power, area and cost effective solutions targeting broad range of embedded devices. In an effort to make one of our leading solutions myAudience-Count embedded-friendly, different possibilities were considered. Here is where FPGA technology came at hand. With Video Analytic target in mind, after extensive market research [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Recently, <a href="http://www.rhondasoftware.com/" title="Rhonda Software" target="_blank">Rhonda Software</a> took yet another step towards more power, area and cost effective solutions targeting broad range of embedded devices. In an effort to make one of our leading solutions <a title="myAudience-Count" href="http://www.myaudience.com/count/overview" target="_blank">myAudience-Count</a> embedded-friendly, different possibilities were considered. Here is where <b>FPGA</b> technology came at hand.</p>
<p><span id="more-175"></span></p>
<p>With <b>Video Analytic</b> target in mind, after extensive market research it was decided to use <a href="http://www.latticesemi.com/products/applicationcutsheets/hdr60cutsheet.cfm" title="Lattice HDR-60 development kit" target="_blank">Lattice HDR-60 development kit</a> as a base platform for our <b>Embedded Count</b> solution. The selected kit is a good choice for several reasons, among which are: mounted 1280&#215;960 camera sensor, Ethernet PHY, DDR2 memory, 2 USB ports, and of course the main decision driver – <a href="http://www.latticesemi.com/products/fpga/ecp3" title="Lattice ECP3 FPGA" target="_blank">Lattice ECP3 FPGA</a> device with 70K of LUTs, 150KB of embedded EBR memory blocks, 256 DSP multipliers and other useful ASIC components. All of the above come packaged in a rather compact base board accompanied with development toolchain up and ready to use.</p>
<p>It is time now to look at what’s inside of <b>Embedded Count</b> product and unveil some core algorithms and approaches.</p>
<p>
As with the <a title="myAudience-Count" href="http://www.myaudience.com/count/overview" target="_blank">PC version</a> at the heart of the system there is an <b>Optical Flow</b> estimator which is basically a motion tracker capable of calculating for each pixel its position relative to the position of the same pixel within previous and next frame in video sequence. In general, if there is a movement present in some part of video frame, the algorithm has to find its position and direction. For unmoved areas the algorithm has to yield nothing.
</p>
<p>For those who are interested, here comes a piece of technical details. Simply speaking, any change of pixel from frame to frame can be explained by either spatial motion or changing of its brightness over time. The latter can be considered as a temporal motion. More strictly, here is a commonly used differential equation relating pixel’s brightness change to its movement, called <b>Optic Flow Constraint</b>:</p>
<p style="text-align: center">∂I/∂x*Vx + ∂I/∂y*Vy + ∂I/∂t = 0,</p>
<p>where Vx and Vy are components of pixel’s speed in spatial directions. ∂I/∂x, ∂I/∂y, ∂I/∂t  are spatial and temporal partial derivatives. As one can see, the equation is under-determined calling for regularization. The most common way of transforming the problem into a well-posed one is adding a Smoothness Constraint of some form which basically postulates that the adjacent pixels tend to move in the same or similar direction. This constraint which usually comes in a form of a laplacian or some other mixture of second derivatives effectively transforms the original equation into, in general, an over-determined system of linear equations which can be solved approximately with the use of convolutions only. Interested readers may refer to a <a title="FPGA-based Real-time Optical Flow Algorithm Design and Implementation" href="http://ojs.academypublisher.com/index.php/jmm/article/view/02053845" target="_blank">nice article</a> by Zhaoyi Wei et al., where the idea is cleanly explained without too much of an analytic overhead.</p>
<p>So, the building blocks of the <b>Optical Flow</b> algorithm are spatial and temporal <b>derivatives</b>, which call for intermediate frame buffers and <b>convolutions</b>, which require buffers, multiplications, summations and divisions.  Hardware implementation itself dictates some constraints the major of which is that in order to be real time the algorithm has to be non-iterative and fully pipelined. As a new pixel from sensor is produced on each clock cycle, it has to be pushed into the processing pipeline at once before the next pixel becomes ready. The amount of memory for storing intermediate results is strictly limited to 150 Kb in total. And of course, there is no such luxury as floating point calculations.</p>
<p>Fortunately, both convolutions and spatial derivatives require only a limited number of frame lines at a time equal to the size of the convolution kernel. Even better, with the use of <b>shift-register</b> structure with taps, they can be easily pipelined so that one output pixel is produced on every clock cycle while new pixel is being pushed into the pipeline.</p>
<p>Multiplications and divisions are much tougher with <b>FPGA</b>. There are a limited number of fixed-point DSP multipliers within the chip and there are no dividers. Implementing either of them within LUT logic will eat up all of the available resources before long. To overcome the lack of multipliers and dividers, approximate convolution kernels for both smoothing and differentiation were carefully designed. The coefficients as well as their sum were chosen to be powers of two. Thus only summations and shifts were required. The shifts on <b>FPGA</b> are resource-free, because they do not produce additional logic or interconnect. To reduce resources consumption even further the separability of the kernels in spatial directions was highly exploited, which allowed to efficiently transform a 2D sub-problem into an 1D.</p>
<p>The next logical step towards problem simplification was rewriting of the <b>Optical Flow Constraint</b> equation eliminating the ∂I/∂x*Vx term and leaving one spatial and one temporal dimension only. This could be done for this particular problem, because the original task of counting people who crosses a virtual line considers motion in the direction orthogonal to this line only and pays no attention to the parallel movements. With a little quality penalty this greatly reduced the amount of required calculations and freed a lot of <b>FPGA</b> resources.</p>
<p>Additionally, as too detailed motion map was not required for solving the problem, a frame downscaling was implemented which allowed to both lessen the intermediate buffers requirements and reduce working clock frequency and power consumption.</p>
<p>The result of <b>Optical Flow</b> calculation is further combined with the result of <b>Background Model</b> module also implemented in hardware and working in parallel with <b>Optical Flow</b> estimator. What follows is the reduction of the combined field into a line and extracting line segments which correspond to the persons being counted. The result of the reduction is then transferred into a CPU implemented as a soft core on the same chip for final post-processing and transmitting onto <a href="https://portal.myaudience.com/login.php" title="myAudience portal" target="_blank">myAudience portal</a> over Ethernet.</p>
<p>Among other important hardware modules of the system there are: <b>Background Model</b> (mentioned above), <b>Debayer</b> (responsible for converting <b>Bayer</b> pattern coming from sensor to RGB), <b>Tone-mapper</b> (for compressing <b>tonal range</b> of input pixels from 12 to 8 bit), <b>JPEG encoder</b> (for streaming preview frames onto calibration web-UI), Ethernet MAC, DDR2 controller, <b>LM32 CPU</b> + <b>Embedded Linux</b> (for running Ethernet stack, transmitting <b>People Count</b> results onto <a href="https://portal.myaudience.com/login.php" title="myAudience portal" target="_blank">myAudience portal</a>, running web-server and JPEG preview streamer), I2C master (for programming sensor’s registers), UART and others. All of them were successfully fitted into a single 70K LUT <b>FPGA</b> consuming about 85% of available chip resources in both LUTs and memory blocks and forming a finished, production-ready <b>People Count</b> solution targeted embedded systems.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://www.computer-vision-software.com/blog/2012/12/fpga-implementation-of-myaudience-count-overview-and-details/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>CETW participation announcement</title>
		<link>http://www.computer-vision-software.com/blog/2011/04/cetw-participation-announcement/</link>
					<comments>http://www.computer-vision-software.com/blog/2011/04/cetw-participation-announcement/#respond</comments>
		
		<dc:creator><![CDATA[Alexander Gavrik]]></dc:creator>
		<pubDate>Mon, 04 Apr 2011 00:44:03 +0000</pubDate>
				<category><![CDATA[Demo video]]></category>
		<category><![CDATA[YouTube]]></category>
		<category><![CDATA[announcement]]></category>
		<category><![CDATA[exhibition]]></category>
		<category><![CDATA[myAudience]]></category>
		<category><![CDATA[video]]></category>
		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=165</guid>

					<description><![CDATA[myAudience promo video Rhonda Software will participate in Customer Engagement Technology World (CET World) in San Francisco, April 27-28, 2011. We are pleased to invite you to visit our booth #235. We’ll be glad to have this chance to introduce you our innovative system myAudience &#8211; tool for automated audience measurement for digital signage, kiosks, [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/L5NHfrFKDEA&amp;rel=0&amp;color1=0xd6d6d6&amp;color2=0xf0f0f0"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/L5NHfrFKDEA&amp;rel=0&amp;color1=0xd6d6d6&amp;color2=0xf0f0f0" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></object></p>
<p><a href="http://www.youtube.com/watch?v=L5NHfrFKDEA">myAudience promo video</a></p>
<p>Rhonda Software will participate in Customer Engagement Technology World (CET World) in San Francisco, April 27-28, 2011. We are pleased to invite you to visit our booth #235.</p>
<p>We’ll be glad to have this chance to introduce you our innovative system <strong>myAudience</strong> &#8211; tool for automated audience measurement for digital signage, kiosks, showcases and many others. You can click this special <a title="link" href="https://www.xpressreg.net/register/cetw041/start.asp?p=PAS4GST" target="_blank">link </a>to register.</p>
<p>Your special PRIORITY CODE will automatically appear with your registration, giving you a FREE exhibits only pass. For up-to-date information about Customer Engagement Technololgy World, please visit <a title="www.CETworld.com" href="http://www.CETworld.com" target="_blank">www.CETworld.com</a>.</p>
<div id="_mcePaste" class="mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow: hidden;">
<p>&nbsp;</p>
<p class="MsoNormal"><span style="font-size: 11pt; font-family: 'Calibri','sans-serif';" lang="EN-US">Rhonda will participate in Customer Engagement Technology World (CET World) in San Francisco, April 27-28, 2011. We are pleased to invite you to visit our booth #235.</span></p>
<p class="MsoNormal">
<p class="MsoNormal"><span style="font-size: 11pt; font-family: 'Calibri','sans-serif';" lang="EN-US">We’ll be glad to have this chance to introduce you our innovative system myAudience &#8211; tool for automated audience measurement for digital signage, kiosks, showcases and many others. Please click this special link to register <a href="https://www.xpressreg.net/register/cetw041/start.asp?p=PAS4GST">https://www.xpressreg.net/register/cetw041/start.asp?p=PAS4GST</a>.</span></p>
<p class="MsoNormal">
<p class="MsoNormal"><span style="font-size: 11pt; font-family: 'Calibri','sans-serif';" lang="EN-US">Your special PRIORITY CODE will automatically appear with your registration, giving you a FREE exhibits only pass. For up-to-date information about Customer Engagement Technololgy World, please visit <a href="http://www.cetworld.com/">www.CETworld.com</a>.</span></p>
</div>
]]></content:encoded>
					
					<wfw:commentRss>http://www.computer-vision-software.com/blog/2011/04/cetw-participation-announcement/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Fine tuning of compiler options to increase application performance</title>
		<link>http://www.computer-vision-software.com/blog/2011/03/fine-tuning-of-compiler-options-to-increase-application-performance/</link>
					<comments>http://www.computer-vision-software.com/blog/2011/03/fine-tuning-of-compiler-options-to-increase-application-performance/#comments</comments>
		
		<dc:creator><![CDATA[Alexander Permyakov]]></dc:creator>
		<pubDate>Mon, 21 Mar 2011 01:27:57 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=163</guid>

					<description><![CDATA[Performance is essential for video analytic applications since algorithms are usually computationally heavy and such systems are supposed to work almost in real time. From one side it can be increased by improving &#38; changing algorithms. This is a major way since it allows to increase performance dramatically. From another side performance can be increased [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Performance is essential for video analytic applications since algorithms are usually computationally heavy and such systems are supposed to work almost in real time. From one side it can be increased by improving &amp; changing algorithms. This is a major way since it allows to increase performance dramatically. From another side performance can be increased little bit more by relatively simple way – using of good compiler and by tuning of compile options. Let see how it can be done in real programs.</p>
<p><span id="more-163"></span></p>
<p><strong>For the first example</strong> I used LAME encoder (<a href="http://lame.sourceforge.net/">http://lame.sourceforge.net/</a>) . Why LAME? First of all because it open source and I can recompile it with different compilers and options. In the second place the simplicity of performance measurement. Performance will be a time required to reencode mp3 file.  In the third place it shows well determinate results what allow better understand how different compile options affect speed.</p>
<p>The testing has been performed on computers with different CPUs under Windows operation system.</p>
<p>Intel Pentium 4 3GHz<br />
Intel Core 2 Duo 2.8 GHz<br />
AMD Athlon2x4 (635) 2.9 GHz overclocked to 3.3 GHz<br />
Intel Core i5 (2500) 3.3 GHz</p>
<p>Compilation has been done by VisualStudio9 and GCC4.5.1(using MinGW)</p>
<p>Encoding time has been measured 10 times and average value placed to the table.</p>
<p>As the base 0.00% I used safe options (-O3 -march=prescott -fomit-frame-pointer -mfpmath=sse) that will work on most modern AMD and Intel CPUs. Option -march=core2 may use ssse3 instructions and therefore code may fail to work on AMD and Intel Pentimum 4 family CPUs.</p>
<p><strong>Intel Pentium 4 3GHz</strong></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>Compiler</td>
<td>Compiler options</td>
<td>Average Time</td>
<td>%</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse -ffast-math -profile-use</td>
<td>13.206153 sec</td>
<td>-7.83 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse -profile-use</td>
<td>13.537400 sec</td>
<td>-5.52 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse -ffast-math</td>
<td>13.999892 sec</td>
<td>-2.29 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse</td>
<td>14.328020 sec</td>
<td>0.00 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -fomit-frame-pointer -mfpmath=sse</td>
<td>14.621770 sec</td>
<td>2.05 %</td>
</tr>
<tr>
<td>Visual_Studio_9</td>
<td>/GS- /fp:fast /O2</td>
<td>14.646769 sec</td>
<td>2.22 %</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<ol>
<li>Optimization to prescott architecture gives 2% speed increase.</li>
<li>–ffast-math gives 2% more</li>
<li>Profile guided optimization gives 5% speed increase</li>
</ol>
<p>&nbsp;</p>
<p><strong>Intel Core 2 Duo 2.8 GHz</strong></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>Compiler</td>
<td>Compiler options</td>
<td>Average Time</td>
<td>%</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=core2 -fomit-frame-pointer   -mfpmath=sse -ffast-math -profile-use</td>
<td>7.818235 sec</td>
<td>-6.65 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=core2 -fomit-frame-pointer   -mfpmath=sse -profile-use</td>
<td>7.824039 sec</td>
<td>-6.58 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse -ffast-math -profile-use</td>
<td>7.893243 sec</td>
<td>-5.75 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse -profile-use</td>
<td>7.976644 sec</td>
<td>-4.75 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=core2 -fomit-frame-pointer   -mfpmath=sse -ffast-math</td>
<td>8.234858 sec</td>
<td>-1.67 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=core2 -fomit-frame-pointer   -mfpmath=sse</td>
<td>8.374867 sec</td>
<td>0.00 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse -ffast-math</td>
<td>8.415269 sec</td>
<td>0.48 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse</td>
<td>8.423270 sec</td>
<td>0.58 %</td>
</tr>
<tr>
<td>Visual_Studio_9</td>
<td>/GS- /fp:fast /O2</td>
<td>8.814092 sec</td>
<td>5.24 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -fomit-frame-pointer -mfpmath=sse</td>
<td>9.224519 sec</td>
<td>10.15 %</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<ol>
<li>Optimization to core2 architecture gives 10% speed increase.</li>
<li>–ffast-math gives only 1% increase</li>
<li>Profile guided optimization gives 6% increase</li>
</ol>
<p>&nbsp;</p>
<p><strong>Intel Core i5 </strong><strong>(2500) </strong><strong>3.3 GHz</strong></p>
<p>There is no special -march option for core i3,5,7 CPUs.  Option -march=core2 can be used for them.</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>Compiler</td>
<td>Compiler options</td>
<td>Average Time</td>
<td>%</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=core2 -fomit-frame-pointer   -mfpmath=sse -ffast-math -profile-use</td>
<td>4.059390 sec</td>
<td>-8.52 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse -ffast-math -profile-use</td>
<td>4.093767 sec</td>
<td>-7.75 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=core2 -fomit-frame-pointer   -mfpmath=sse -ffast-math</td>
<td>4.156268 sec</td>
<td>-6.34 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse -ffast-math</td>
<td>4.200015 sec</td>
<td>-5.35 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=core2 -fomit-frame-pointer   -mfpmath=sse -profile-use</td>
<td>4.253143 sec</td>
<td>-4.15 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse -profile-use</td>
<td>4.321892 sec</td>
<td>-2.61 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse</td>
<td>4.437519 sec</td>
<td>0.00 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=core2 -fomit-frame-pointer   -mfpmath=sse</td>
<td>4.468770 sec</td>
<td>0.70 %</td>
</tr>
<tr>
<td>Visual_Studio_9</td>
<td>/GS- /fp:fast /O2</td>
<td>4.737522 sec</td>
<td>6.76 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -fomit-frame-pointer -mfpmath=sse</td>
<td>4.815647 sec</td>
<td>8.52 %</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<ol>
<li>Optimization to core2 architecture gives 9% speed increase.</li>
<li>–ffast-math gives  6% increase</li>
<li>Profile guided optimization gives 4% increase</li>
</ol>
<p>&nbsp;</p>
<p><strong>AMD Athlon2x4 (635) 2.9 GHz overclocked to 3.3 GHz</strong></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>Compiler</td>
<td>Compiler options</td>
<td>Average Time</td>
<td>%</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=amdfam10 -fomit-frame-pointer   -mfpmath=sse -ffast-math -profile-use</td>
<td>6.078386 sec</td>
<td>-6.14 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=amdfam10 -fomit-frame-pointer   -mfpmath=sse -ffast-math</td>
<td>6.170114 sec</td>
<td>-4.73 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse -ffast-math -profile-use</td>
<td>6.308954 sec</td>
<td>-2.58 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=amdfam10 -fomit-frame-pointer   -mfpmath=sse -profile-use</td>
<td>6.388826 sec</td>
<td>-1.35 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=amdfam10 -fomit-frame-pointer   -mfpmath=sse</td>
<td>6.476186 sec</td>
<td>0.00 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse -profile-use</td>
<td>6.527979 sec</td>
<td>0.80 %</td>
</tr>
<tr>
<td>Visual_Studio_9</td>
<td>/GS- /fp:fast /O2</td>
<td>6.942938 sec</td>
<td>7.21 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse -ffast-math</td>
<td>7.293316 sec</td>
<td>12.62 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse</td>
<td>7.372564 sec</td>
<td>13.84 %</td>
</tr>
<tr>
<td>GCC4.5.1</td>
<td>-O3 -fomit-frame-pointer -mfpmath=sse</td>
<td>7.661477 sec</td>
<td>18.30 %</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<ol>
<li>Optimization to amdfam10 architecture gives 18% speed increase</li>
<li>–ffast-math gives 5 %</li>
<li>Profile guided optimization gives only 1%.</li>
</ol>
<p>&nbsp;</p>
<p><strong>Total results</strong></p>
<p><strong> </strong>Optimization to particular architecture and profile guided optimization may give up to 20 % speed increase.</p>
<p>&nbsp;</p>
<p>As I already said  LAME is simple example. Let see how performance options affect real video analytic application .</p>
<p>&nbsp;</p>
<p><strong>For the second example</strong> I used critical part of real video analytic application (myAudience). It uses boost, opencv and  ffmpeg libraries. Also it runs in several threads. In comparison with LAME encoder performance measurement for this application was not so simple. Moreover because of inaccuracy of measurements in multithreading dynamic enviroment results were not so well determinate. So I have prepared just one table which shows results in general how I understand them.</p>
<p>Compilation has been done by GCC4.5.2 and GCC4.1.2 on CentOS_5.5</p>
<p>&nbsp;</p>
<p><strong>Intel Core i5 </strong><strong>(2500) </strong><strong>3.3 GHz</strong></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>Compiler</td>
<td>Compiler options</td>
<td>Average Time</td>
<td>%</td>
</tr>
<tr>
<td>GCC4.5.2</td>
<td>-O3 -march=core2 -fomit-frame-pointer   -mfpmath=sse -ffast-math -profile-use</td>
<td>19591.16</td>
<td>-4.90 %</td>
</tr>
<tr>
<td>GCC4.5.2</td>
<td>-O3 -march=core2 -fomit-frame-pointer   -mfpmath=sse -profile-use</td>
<td>19873.74</td>
<td>-3.53 %</td>
</tr>
<tr>
<td>GCC4.5.2</td>
<td>-O3 -march=core2 -fomit-frame-pointer   -mfpmath=sse -ffast-math</td>
<td>20010.55</td>
<td>-2.86 %</td>
</tr>
<tr>
<td>GCC4.5.2</td>
<td>-O3 -march=core2 -fomit-frame-pointer   -mfpmath=sse</td>
<td>20410.36</td>
<td>-2.09 %</td>
</tr>
<tr>
<td>GCC4.5.2</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse -ffast-math</td>
<td>20410.36</td>
<td>-0.92 %</td>
</tr>
<tr>
<td>GCC4.1.2</td>
<td>-O3 -march=core2 -fomit-frame-pointer   -mfpmath=sse -ffast-math</td>
<td>20532.91</td>
<td>-0.33 %</td>
</tr>
<tr>
<td>GCC4.5.2</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse</td>
<td>20600.55</td>
<td>0.00 %</td>
</tr>
<tr>
<td>GCC4.1.2</td>
<td>-O3 -march=core2 -fomit-frame-pointer   -mfpmath=sse</td>
<td>20816.26</td>
<td>1.05 %</td>
</tr>
<tr>
<td>GCC4.1.2</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse -ffast-math</td>
<td>21962.44</td>
<td>6.61 %</td>
</tr>
<tr>
<td>GCC4.1.2</td>
<td>-O3 -march=prescott -fomit-frame-pointer   -mfpmath=sse</td>
<td>22221.88</td>
<td>7.87 %</td>
</tr>
</tbody>
</table>
<p>What can we conclude after that? Few things</p>
<ol>
<li>GCC4.5.2 little bit faster than GCC4.1.2 plus it allow to use profile guided optimization, and “amdfam10”, “atom” architecture options.</li>
<li>Profile guided optimization give about 4% speed increase.</li>
<li>–ffast-math gives about 2% speed increase</li>
</ol>
<p>&nbsp;</p>
<p>As you can see, tuning compiler options allows to get real improvement in performance, not so huge sometimes, but almost free, so it should be kept in mind.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://www.computer-vision-software.com/blog/2011/03/fine-tuning-of-compiler-options-to-increase-application-performance/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Testing video analytic algorithms</title>
		<link>http://www.computer-vision-software.com/blog/2011/01/testing-video-analytic-algorithms/</link>
					<comments>http://www.computer-vision-software.com/blog/2011/01/testing-video-analytic-algorithms/#respond</comments>
		
		<dc:creator><![CDATA[Yuri Vashchenko]]></dc:creator>
		<pubDate>Wed, 19 Jan 2011 09:09:05 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=153</guid>

					<description><![CDATA[A modern video analytic system depending on business/customer requirements should work in different situations/conditions. Complex, noisy background with many different objects/textures, changing lighting conditions, shadows, lack of light, weather conditions (for outdoor system installations) like rain, snow, fog and others, motion blur, camera movements, cameral sensor quality, camera resolution, camera focus issues, camera internal optimizations, [&#8230;]]]></description>
										<content:encoded><![CDATA[<p style="text-align: justify;">A modern video analytic system depending on business/customer requirements should work in different situations/conditions. Complex, noisy background with many different objects/textures, changing lighting conditions, shadows, lack of light, weather conditions (for outdoor system installations) like rain, snow, fog and others, motion blur, camera movements, cameral sensor quality, camera resolution, camera focus issues, camera internal optimizations, color temperature, end many other factors make development of the good object recognition software a challenging, almost impossible task. In addition, the usual requirement is that the system should work in real time, which makes this task even more difficult.<span id="more-153"></span><br />
So, even having current high-performance hardware, developers have to find a balance between the algorithm quality and speed (performance). Fixing a small quality issue sometimes causes significant performance degradation.<br />
To keep this under control, a consistent unit testing should be performed with every algorithm change. To do this, Rhonda Software uses the unit test approach as described below:</p>
<ol>
<li>A set of metrics is prepared. These metrics definitions describe “ground rules”, i.e. how actual logs from the system under test is interpreted, what is considered correct and what is not correct. For example, for people counting metric the following definition may be used:PEOPLE COUNTING<br />
&lt;visitors_number&gt; total number of visitors in test frame range = Correct + Missing + Unexpected + False<br />
Real visitors (all found and not found visitors besides False) = Correct + Missing + Unexpected<br />
Correct: Log visitors associated with test visitors, even if more than one log visitor is associated with one test visitor (only if test visitor had Hard detection status between frames were previous and next log visitor were correlated).<br />
Missing: Not found in log<br />
Unexpected: Log visitor is associated with earlier associated test visitor, but there is no Hard visitor detection status between these log visitors.<br />
False: Log visitor is not associated with any test visitor</li>
<li>For each metric a set of KPIs (Key performance indicators) is defined. For example, for people counting metric the following KPIs may be defined:<br />
# of Total visitors<br />
# of Real visitors<br />
# ofFalse visitors<br />
# of Missing visitors<br />
False visitor rate (percent)<br />
Missing visitor rate (percent)<br />
Counting error rate (percent)</li>
<li>Some KPIs may have a goal. For example, we may want to have Counting error rate less than 3%.</li>
<li>A set of test videos is created. Typically, there are dozens of videos prepared for the project to cover as many different situations/conditions as possible.</li>
<li>Project specific marker tool is used to create a special “markup”, or Meta information describing the objects located at each of input video. Usually, it is an xml file having the same name as an input video file. A specially trained engineer uses this tool to open a video file, go through selected frames and mark objects on them. For instance, for demography detection software, an operator may mark all persons found on a frame, specify coordinates location of their faces and add special attributes for every face like gender, ethnicity or age category. Some objects may be marked as “hard examples”. It specifies that this object is hard to detect/recognized due to different situations, like had motion blur, partially cover by another object, etc. By other words, a hard example is an object that potentially could be detected/recognized by the software, but it is not very likely, so it is ok if the software does not detect/recognize this object. Markup files are stored together with the video test files on a dedicated server for easy access.</li>
<li>Software under test is executed in a special logging mode. This mode tells the software to log everything it detects/recognizes and put it into a special (usually xml) log file. A specially prepared set of video files is given to the software version as an input. For each input video file a corresponding xml log is created.</li>
<li>Another project-specific tool, comparer is then used to get KPI values. The tool uses prepared markup (see 5) and actual data values from log (see 6). As a result, set of KP values is generated.</li>
</ol>
<p style="text-align: justify;">Metrics, KPIs and markup are created once per project/video. Testing and metrics calculation can be made for every release to see how this release changed in terms of quality and speed. This allows quickly detecting and fixing possible quality/speed degradations introduced in the release. In addition, when tested periodically, project management can see how the system evolves over the time in terms of quality/performance.<br />
While making video for testing and markup of this video requires people to do, most of other unit testing activities could be performed automatically which helps keeping the quality and performance under control and requires little effort to perform. All of above allows us to develop state of the art, highly competitive software.</p>
<p style="text-align: justify;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="350" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://www.youtube.com/v/0uJu8IEiDbI" /><embed type="application/x-shockwave-flash" width="425" height="350" src="http://www.youtube.com/v/0uJu8IEiDbI"></embed></object></p>
<p style="text-align: justify;">The video above explains the process of markering a video file.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://www.computer-vision-software.com/blog/2011/01/testing-video-analytic-algorithms/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Face Recognition</title>
		<link>http://www.computer-vision-software.com/blog/2010/09/face-recognition/</link>
					<comments>http://www.computer-vision-software.com/blog/2010/09/face-recognition/#comments</comments>
		
		<dc:creator><![CDATA[Sergey Koulik]]></dc:creator>
		<pubDate>Fri, 10 Sep 2010 01:51:42 +0000</pubDate>
				<category><![CDATA[Face recognition]]></category>
		<category><![CDATA[Gabor wavelet]]></category>
		<category><![CDATA[Object Recognition]]></category>
		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=135</guid>

					<description><![CDATA[2D face recognition is an extensively studied, but still evolving subject of research. Various strategies including statistical approaches, hidden Markov models, neural networks, template based and feature based matching have been proposed. Here we briefly present our implementation which is based on past research and achieves state-of-the-art recognition performance on considerably low resolution input facial [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>2D face recognition is an extensively studied, but still evolving  subject of research. Various strategies including statistical  approaches, hidden Markov models, neural networks, template based and  feature based matching have been proposed.  Here we briefly present our  implementation which is based on past research and achieves  state-of-the-art recognition performance on considerably low resolution  input facial images.<br />
Our approach can be divided into three independent phases: Facial  landmarks library construction (offline), Building of facial descriptor  (once per novel image) and Facial descriptors matching.</p>
<p style="text-align: center;"><a href="http://www.computer-vision-software.com/blog/wp-content/uploads/2010/09/result_11.png"><img loading="lazy" decoding="async" class="size-full wp-image-139 aligncenter" title="Face recognition result on live video sequence" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2010/09/result_11.png" alt="Face recognition result on live video sequence" width="640" height="141" srcset="http://www.computer-vision-software.com/blog/wp-content/uploads/2010/09/result_11.png 640w, http://www.computer-vision-software.com/blog/wp-content/uploads/2010/09/result_11-300x66.png 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /></a></p>
<p><span id="more-135"></span><br />
<strong>Facial landmarks library construction</strong><br />
A set of training images is marked by hand. Coordinates of important  facial landmarks (such as lips’ corners, nose tip, etc.) are stored in a  database for further processing.<br />
Using information about landmarks position it is easy to geometrically transform and align training images.<br />
Illumination correction is applied to transformed images in order to get  rid of shadows and glares and normalize overall exposure.<br />
Gabor jets are then extracted from normalized images in every landmark  location. Extracted jets are stored in facial landmarks library for  further using during novel images processing.</p>
<p><strong>Building of facial descriptor</strong><br />
Having received a novel facial image we first try to locate approximate  eyes position using our hybrid method of Viola-Jones and Bayesian  classifier. The purpose why eyes coordinates are required is twofold:  they are used to geometrically wrap and align input image and also to  get initial estimate of coordinates of other facial landmarks.<br />
Illumination correction and background clipping is then performed.<br />
Starting from approximate eyes position and using samples from facial  landmarks library we iteratively find precise locations of all facial  landmarks on novel face.<br />
Found landmarks positions are then used to extract Gabor jets and  construct informative facial descriptor. Original input image is not  required any more after this step.</p>
<p><strong>Facial descriptors matching</strong><br />
The last and the simplest step is matching two facial descriptors which  yields a similarity measure between two faces – a real number between 0  (nothing in common) and 1 (complete match). A threshold found by  experiment is used to make decision whether the faces belong to the same  or different persons.<br />
Descriptors matching is several orders of magnitude faster than  descriptor building which makes it possible to match new face against a  database of known persons in moderate time.</p>
<p><strong>Some technical details</strong><br />
Working face size: 45&#215;45 px<br />
Descriptor building time: 300ms on P4 1300 MHz (single core).<br />
Descriptors matching: 2ms on P4 1300 MHz (single core).<br />
Recognition rate: Feret fa/fb: 88%, Yale Faces: 86%, Faces in wild: 73%. Both false positives and false negatives considered.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://www.computer-vision-software.com/blog/2010/09/face-recognition/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>Currency recognition using cortex-like model.</title>
		<link>http://www.computer-vision-software.com/blog/2010/08/currency-recognition-using-cortex-like-model/</link>
					<comments>http://www.computer-vision-software.com/blog/2010/08/currency-recognition-using-cortex-like-model/#respond</comments>
		
		<dc:creator><![CDATA[Igor Stepura]]></dc:creator>
		<pubDate>Mon, 09 Aug 2010 07:05:18 +0000</pubDate>
				<category><![CDATA[Currency recognition]]></category>
		<category><![CDATA[HMAX]]></category>
		<category><![CDATA[Object Recognition]]></category>
		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=125</guid>

					<description><![CDATA[Currency recognition seems to be one of the popular topic in &#8220;applied&#8221; computer vision. There are a lot of articles, blog entries describing different approaches to currency recognition. In this post I&#8217;ll share my experience of using so-called HMAX model. Introduction HMAX aims to model hierarchical object recognition in cortex. I won&#8217;t get into details [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Currency recognition seems to be one of the popular topic in &#8220;applied&#8221; computer vision. There are a lot of  articles, blog entries describing different approaches to currency recognition. In this post I&#8217;ll share my experience of using so-called HMAX model.</p>
<p><span id="more-125"></span></p>
<p><strong>Introduction</strong></p>
<p>HMAX aims to model hierarchical object recognition in cortex. I won&#8217;t get into details of HMAX model, just provide some useful links for curious readers:<br />
<a href=" http://riesenhuberlab.neuro.georgetown.edu/hmax.html"><br />
http://riesenhuberlab.neuro.georgetown.edu/hmax.html</a></p>
<p><a href="http://cbcl.mit.edu/cbcl/publications/index-pubs.html">http://cbcl.mit.edu/cbcl/publications/index-pubs.html</a></p>
<p>My approach in using HMAX for currency recognition was pretty simple.</p>
<p>1. Generate proper С1-feature dictionary<br />
2. Using C1-feature dictionary, generate C2 vectors for images in training dataset<br />
3. Train multi-class SVM classifier using C2 vectors.<br />
4. Test classifier on testing dataset<br />
5. PROFIT</p>
<p><strong>C1 dictionary generation</strong><br />
My initial approach was to generate dictionary automatically using an &#8220;interesting point&#8221; detector and then generate C-1 patches of size corresponding to the size of detected image structure. Hessian-Laplace (see Mikolajczyk K. and Schmid, C. 2004. ) method seemed to suit well for this task, since it  detects characteristic scale of interesting points. My implementation of Hessian-Laplace worked reasonable fine, however number of interesting points it detected was big, so it was pretty hard for my C1 extractor to decide which one of these points was really &#8220;interesting&#8221; for currency recognition.<br />
As a result &#8211; none of my automatically generated dictionaries (which contained about 1000 samples) produce suitable classification outputs.</p>
<p>So I decided to start from smaller dictionary, which would contain hand-picked, really descriptive patches from all kind of bills. For each image in C1 dataset I took 8 patches ( see example of pacthes below). All images in C1 dataset were resized to have width 300 pixels. Size of C1 dictionary now became 88. </p>
<p><a href="http://www.computer-vision-software.com/blog/wp-content/uploads/2010/08/1_face_000.bmp"><img decoding="async" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2010/08/1_face_000.bmp" alt="" title="1_face_000" class="aligncenter size-full wp-image-126" /></a></p>
<p><strong>Classifier training</strong><br />
The size of my training dataset was 337 images of different dollar bills of all classes (1 to 100) + set of &#8220;background&#8221; images.</p>
<p>I used LibSVM for classifier training and testing, using RBF and Linear classifier kernels.</p>
<p>To train models with RBF kernels I used script easy.py from LibSVM &#8211; this handy script automatically scales training data and the searches for the best C/gamma parameters of the kernel.<br />
Linear classifiers were trained using semi-automated approach &#8211; I scaled training data first, then used grid.py to find best value for C parameter of the kernel. </p>
<p>Something like that:<br />
 <code>svm-scale -s newdict.range newdict.l > newdict.scale</p>
<p>./grid.py -log2g 1,1,1 -log2c -5,15,0.5 -t 0 newdict.scale</p>
<p>svm-train -t 0 -c 0.353553390593 newdict.scale newdict.model</code></p>
<p>And for testing:<br />
<code>svm-scale -r newdict.range newdict.t > newdict.t.scale</p>
<p>svm-predict newdict.t.scale newdict.model newdict.model.predict</code></p>
<p><strong>Experiment results</strong></p>
<p>Best classification accuracy I&#8217;ve reached so far is <strong>88.62%</strong> using linear classifier. </p>
<p><strong>Conclusions and future work</strong></p>
<p>HMAX model has proved successful in classification of currency images and seem to have potential for better results.</p>
<p>Possible directions toward better classification could be:<br />
1. Brightness correction. HMAX implementation I used seems to be pretty sensitive to brightness changes. I&#8217;ll need to investigate this more deeply and if necessary &#8211; normalize trainig/testing images to get rid of brightness-related issues.</p>
<p>2. Quality of C1-dictionary. While my current dictionary proved to be good enough to recognize dollar bill classes, I suppose it could be improved. For example &#8211; data there could be more patches per bill class, taken for different layers (bands) of C1 &#8220;pyramid&#8221;. The size of the features may also vary to achieve better results.</p>
<p>3. HMAX model tuning. Perhaps model modification according to approach of Jim Mutch и David G. Lowe (<a href="http://www.cs.ubc.ca/~lowe/papers/08mutch.pdf"> PDF</a>) would give better recognition results.</p>
<p>4. Use Ada-Boost in addition to SVM for better model training.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://www.computer-vision-software.com/blog/2010/08/currency-recognition-using-cortex-like-model/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Compiling OpenCV for Android using NDK 3</title>
		<link>http://www.computer-vision-software.com/blog/2010/04/android/</link>
					<comments>http://www.computer-vision-software.com/blog/2010/04/android/#comments</comments>
		
		<dc:creator><![CDATA[Alexander Permyakov]]></dc:creator>
		<pubDate>Thu, 22 Apr 2010 06:01:50 +0000</pubDate>
				<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[face detection]]></category>
		<category><![CDATA[NDK]]></category>
		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=116</guid>

					<description><![CDATA[Build platform: Ubuntu 9.10 Target platform: Android Download and prepare OpenCV library source code. 1. Download the latest version of OpenCV (http://sourceforge.net/project/showfiles.php?group_id=22870). 2. As build platform is Linux, select linux version (for example OpenCV2.1.0.tat.bz). 3. Unpack somewhere to home dir. Download and prepare cross-compiler 1. Download Android NDK 3 for Linux (http://developer.android.com/sdk/ndk/index.html) 2. Unpack it [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="http://www.computer-vision-software.com/blog/wp-content/uploads/2010/04/Picture-18.jpg"></a></p>
<p>Build platform: Ubuntu 9.10<br />
Target platform: Android</p>
<p><strong>Download and prepare OpenCV library source code. </strong></p>
<p><strong>1. </strong>Download the latest version of OpenCV (<a href="http://sourceforge.net/project/showfiles.php?group_id=22870" target="_blank">http://sourceforge.net/project/showfiles.php?group_id=22870</a>).</p>
<p>2. As build platform is Linux, select linux version (for example<em> OpenCV2.1.0.tat.bz</em>).</p>
<p><span id="more-116"></span></p>
<p><strong>3. </strong>Unpack somewhere to home dir.</p>
<p><strong>Download and prepare cross-compiler</strong></p>
<p><strong><span style="font-weight: normal;">1. Download Android NDK 3 for Linux (<a href="http://developer.android.com/sdk/ndk/index.html" target="_blank">http://developer.android.com/sdk/ndk/index.html</a>)</span></strong></p>
<p><strong><span style="font-weight: normal;">2. Unpack it to <em>~/android_ndk_3/</em></span></strong></p>
<p><strong><span style="font-weight: normal;"><em><span style="font-style: normal;"><strong>3. </strong>Then run <em>~/android_ndk_3/build/host-setup.sh</em> but first fix the error in line 119</span></em></span></strong></p>
<p><strong><span style="font-weight: normal;"><em><span style="font-style: normal;">Change</span></em></span></strong></p>
<p><strong><span style="font-weight: normal;"><em><span style="font-style: normal;">if [ &#8220;$result&#8221; = &#8220;Pass&#8221; ] ; then</span></em></span></strong></p>
<p><strong><span style="font-weight: normal;"><em><span style="font-style: normal;">to</span></em></span></strong></p>
<p><strong><span style="font-weight: normal;"><em><span style="font-style: normal;">if [ &#8220;$result&#8221; == &#8220;Pass&#8221; ] ; then</span></em></span></strong></p>
<p><strong><span style="font-weight: normal;"><em><span style="font-style: normal;"><strong>4. </strong>Do/install whatever needed to let host-setup.sh complete successful.</span></em></span></strong></p>
<p><strong>Create NDK project/Modify Makefiles</strong></p>
<p>There is one big issue with NKD toolchein. It has trimmed stdc library which does not contain STL. Because of that some files (like <em>cvkdtree.cpp</em> in cv) can not be compiled since they use vector, list and other stuff. The solution is to compile STL from source code. In my OpenCV NDK project I used STL sources from uClibc (<a href="http://www.uclibc.org" target="_blank">http://www.uclibc.org</a>).</p>
<p>The simpliest way to start your OpenCV NDK project is to update <em>hello-jni</em> project with OpenCV source files.</p>
<p>The <em>~/android_ndk_3/apps/hello-jni/project/jni</em> folder of hello-jni project may look like this</p>
<ol>cv<br />
&#8211; hdr<br />
&#8211; src<br />
cvaux<br />
&#8211; hdr<br />
&#8211; src<br />
cxcore<br />
&#8211; hdr<br />
&#8211; src<br />
stl<br />
&#8211; hdr<br />
&#8211; src<br />
Android.mk<br />
hello-jni.c</ol>
<p>The <em>~/android_ndk_3/apps/hello-jni/project/jni/Android.mk</em> may looks like this</p>
<ol>APPS_PATH := $(call my-dir)############################<br />
# stl<br />
############################<br />
include $(CLEAR_VARS)LOCAL_PATH := $(APPS_PATH)/stl/src<br />
LOCAL_C_INCLUDES := $(APPS_PATH)/stl/hdrLOCAL_MODULE := stl<br />
LOCAL_SRC_FILES := string.cpp algorithm.cpp char_traits.cpp iterator.cpp limits.cpp list.cpp vector.cppinclude $(BUILD_STATIC_LIBRARY)############################<br />
# cxcore<br />
############################<br />
include $(CLEAR_VARS)LOCAL_PATH := $(APPS_PATH)/cxcore/src<br />
LOCAL_C_INCLUDES := $(APPS_PATH)/cxcore/hdrLOCAL_CXXFLAGS := -DHAVE_CONFIG_HLOCAL_MODULE := cxcore<br />
LOCAL_SRC_FILES := cxalloc.cpp cxarithm.cpp cxarray.cpp cxcmp.cpp cxconvert.cpp cxcopy.cpp cxdatastructs.cpp cxdrawing.cpp cxdxt.cpp cxerror.cpp cximage.cpp cxjacobieigens.cpp cxlogic.cpp cxlut.cpp cxmathfuncs.cpp cxmatmul.cpp cxmatrix.cpp cxmean.cpp cxmeansdv.cpp cxminmaxloc.cpp cxnorm.cpp cxouttext.cpp cxpersistence.cpp cxprecomp.cpp cxrand.cpp cxsumpixels.cpp cxsvd.cpp cxswitcher.cpp cxtables.cpp cxutils.cpp dummy.cppinclude $(BUILD_STATIC_LIBRARY)############################<br />
# cv<br />
############################<br />
include $(CLEAR_VARS)</p>
<p>LOCAL_PATH := $(APPS_PATH)/cv/src<br />
LOCAL_C_INCLUDES := $(APPS_PATH)/cv/hdr $(APPS_PATH)/cxcore/hdr $(APPS_PATH)/stl/hdr</p>
<p>LOCAL_MODULE := cv<br />
LOCAL_SRC_FILES := cvkdtree.cpp cvaccum.cpp cvadapthresh.cpp cvapprox.cpp cvcalccontrasthistogram.cpp cvcalcimagehomography.cpp cvcalibinit.cpp cvcalibration.cpp cvcamshift.cpp cvcanny.cpp cvcolor.cpp cvcondens.cpp cvcontours.cpp cvcontourtree.cpp cvconvhull.cpp cvcorner.cpp cvcornersubpix.cpp cvderiv.cpp cvdistransform.cpp cvdominants.cpp cvemd.cpp cvfeatureselect.cpp cvfilter.cpp cvfloodfill.cpp cvfundam.cpp cvgeometry.cpp cvhaar.cpp cvhistogram.cpp cvhough.cpp cvimgwarp.cpp cvinpaint.cpp cvkalman.cpp cvlinefit.cpp cvlkpyramid.cpp cvmatchcontours.cpp cvmoments.cpp cvmorph.cpp cvmotempl.cpp cvoptflowbm.cpp cvoptflowhs.cpp cvoptflowlk.cpp cvpgh.cpp cvposit.cpp cvprecomp.cpp cvpyramids.cpp cvpyrsegmentation.cpp cvrotcalipers.cpp cvsamplers.cpp cvsegmentation.cpp cvshapedescr.cpp cvsmooth.cpp cvsnakes.cpp cvstereobm.cpp cvstereogc.cpp cvsubdivision2d.cpp cvsumpixels.cpp cvsurf.cpp cvswitcher.cpp cvtables.cpp cvtemplmatch.cpp cvthresh.cpp cvundistort.cpp cvutils.cpp dummy.cpp</p>
<p>LOCAL_STATIC_LIBRARIES := cxcore stl</p>
<p>include $(BUILD_STATIC_LIBRARY)</p>
<p>############################<br />
# cvaux<br />
############################<br />
include $(CLEAR_VARS)</p>
<p>LOCAL_PATH := $(APPS_PATH)/cvaux/src<br />
LOCAL_C_INCLUDES := $(APPS_PATH)/cvaux/hdr $(APPS_PATH)/cv/hdr $(APPS_PATH)/cv/src $(APPS_PATH)/cxcore/hdr $(APPS_PATH)/stl/hdr</p>
<p>LOCAL_MODULE := cvaux<br />
LOCAL_SRC_FILES := camshift.cpp cvaux.cpp cvauxutils.cpp cvbgfg_acmmm2003.cpp cvbgfg_codebook.cpp cvbgfg_common.cpp cvbgfg_gaussmix.cpp cvcalibfilter.cpp cvclique.cpp cvcorrespond.cpp cvcorrimages.cpp cvcreatehandmask.cpp cvdpstereo.cpp cveigenobjects.cpp cvepilines.cpp cvface.cpp cvfacedetection.cpp cvfacetemplate.cpp cvfindface.cpp cvfindhandregion.cpp cvhmm.cpp cvhmm1d.cpp cvhmmobs.cpp cvlcm.cpp cvlee.cpp cvlevmar.cpp cvlevmarprojbandle.cpp cvlevmartrif.cpp cvlines.cpp cvlmeds.cpp cvmat.cpp cvmorphcontours.cpp cvmorphing.cpp cvprewarp.cpp cvscanlines.cpp cvsegment.cpp cvsubdiv2.cpp cvtexture.cpp cvtrifocal.cpp cvvecfacetracking.cpp cvvideo.cpp decomppoly.cpp dummy.cpp enmin.cpp extendededges.cpp precomp.cpp vs/bgfg_estimation.cpp vs/blobtrackanalysis.cpp vs/blobtrackanalysishist.cpp vs/blobtrackanalysisior.cpp vs/blobtrackanalysistrackdist.cpp vs/blobtrackgen1.cpp vs/blobtrackgenyml.cpp vs/blobtrackingauto.cpp vs/blobtrackingcc.cpp vs/blobtrackingccwithcr.cpp vs/blobtrackingkalman.cpp vs/blobtrackinglist.cpp vs/blobtrackingmsfg.cpp vs/blobtrackingmsfgs.cpp vs/blobtrackpostprockalman.cpp vs/blobtrackpostproclinear.cpp vs/blobtrackpostproclist.cpp vs/enteringblobdetection.cpp vs/enteringblobdetectionreal.cpp vs/testseq.cpp</p>
<p># failed to compile<br />
#cv3dtracker.cpp</p>
<p>LOCAL_STATIC_LIBRARIES := cv cxcore stl</p>
<p>include $(BUILD_STATIC_LIBRARY)</ol>
<p>The <em>~/android_ndk_3/apps/hello-jni/Application.mk</em> file needs to be updated as follows</p>
<ol>APP_PROJECT_PATH := $(call my-dir)/project<br />
APP_MODULES      := stl cxcore cv cvaux hello-jni</ol>
<p>To build the project go to <em>~/android_ndk_3</em> and type</p>
<ol>make APP=hello-jni</ol>
<p>Of course there will be compile issues. Understand and fix them. Easiest cases are related to syntax mismatch between different compilers. In more complicated cases some code should be commented out. For example usage of libs with optimizations for Intel processor is not needed for ARM.</p>
<p>HighGui is also can be built but only partially. Simply remove files that causing problems from Android.mk. In my case the rest of files were enough to use cvLoadImage function for bmp file.</p>
<p><strong>Running facedetect openCV example</strong></p>
<p>There is no way to run native C code as separate application on Android. Instead native C functions can be called from Java apps. Because of that I made native function FaceDetect using OpenCV example application facedetect.c.</p>
<p>The declaration looks like this</p>
<ol>void<br />
Java_com_example_hellojni_HelloJni_FaceDetect( JNIEnv* env, jobject thiz, jbyteArray jyuv_buff, int w, int h, jbyteArray jbgra_buff)<br />
{<br />
&#8230;<br />
}</ol>
<p>This function takes YUV_NV21 buffer (preview from camera captured by Java app), converts it to BGRA8888, searches the faces, draws circles around the faces and returns updated RGBA8888 buffer back to Java app. Java app can draw it on the screen.</p>
<p style="text-align: center;"><a href="http://www.computer-vision-software.com/blog/wp-content/uploads/2010/04/Picture-18.jpg"><img loading="lazy" decoding="async" class="aligncenter" title="Picture 18" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2010/04/Picture-18-300x225.jpg" alt="" width="300" height="225" /></a></p>
]]></content:encoded>
					
					<wfw:commentRss>http://www.computer-vision-software.com/blog/2010/04/android/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
	</channel>
</rss>
