<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
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/">
	<channel>
		<title>Author at Infinum</title>
		<atom:link href="https://infinum.com/blog/author/marin-kreso/feed/" rel="self" type="application/rss+xml" />
		<link></link>
		<description>Building digital products</description>
		<lastBuildDate>Tue, 21 Apr 2026 22:30:50 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>8109https://infinum.com/uploads/2023/08/HERO-Building-a-Recommendation-System-For-a-Culinary-App-min.webp</url>
				</image>
				<title>Building a Tailored Recommendation System for Philips NutriU</title>
				<link>https://infinum.com/blog/building-a-recommendation-system-for-a-culinary-app/</link>
				<pubDate>Fri, 18 Oct 2019 10:05:00 +0000</pubDate>
				<dc:creator>Marin Krešo</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/building-a-recommendation-system-for-a-culinary-app/</guid>
				<description>
					<![CDATA[<p>Recommendation systems are utilized by famous web services like Youtube, Netflix and Spotify to make tailored content suggestions.</p>
<p>The post <a href="https://infinum.com/blog/building-a-recommendation-system-for-a-culinary-app/">Building a Tailored Recommendation System for Philips NutriU</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-148"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-92">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-95"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-93">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-94'
	>
	<em>Note: Since the publishing of this article, the Philips NutriU app has grown in scope and changed its name to HomeID. You can learn more about the project by visiting <a href="https://infinum.com/work/philips-connected-kitchen-appliances/">our work page</a>. </em></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-98"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-96">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-97'
	>
	Recommendation systems play a big part in our lives without us even realizing it. Famous web services like Youtube, Amazon, Netflix, and Spotify use them to make content suggestions tailored to a specific user, improving user experience by a significant margin.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-99">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-100'
	>
	These systems put together tailored playlists, suggest which movie to watch next, or reveal what products are often bought together.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-104"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-102">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-103'
	>
	Various services observe user actions like clicks and likes, and use the gathered data as input for the recommendation system to generate personalized recommendations. Using recommendation systems is a better and faster way of discovering relevant content for different people.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-106"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-105'
	>
	<strong>The </strong><a href="https://infinum.com/news/infinum-and-philips-award-winning-collaboration-on-nutriu/"><strong>award-winning mobile application NutriU</strong></a><strong> is a companion app for Airfryers, blenders, and juicers. It allows users to control their appliances remotely but also helps them create and share recipes and find culinary inspiration.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-109"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-107">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-108'
	>
	When we set out to build a recommendation system for Philips’ NutriU, we realized that while there was plenty of literature online providing an overview of the algorithms and explaining how to train and evaluate such systems, there were scarce resources on how to build recommendation systems for production. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-112"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-110">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-111'
	>
	In this blog post, we take you behind the scenes of our project and show you how we’ve built a high-performance, fast and scalable recommendation system in a real-time setting.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-119"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<a	class="card-simple js-card-simple card-simple--is-ad block-card__card-simple card-simple--has-link js-card-simple-link card-simple__content-align--left"
	data-id="es-113"
	 href='https://infinum.com/ai-readiness-assessment/#form'>

	
	
	<div class="card-simple__content">
		<div class="card-simple__heading-wrap">
			<h2	class='typography typography--size-24-text js-typography card-simple__heading'
	data-id='es-114'
	>
	<strong><strong>If you&#8217;re considering integrating AI into your digital product, the first step is to evaluate your current state. <strong>Fill out our survey and get a free personalized assessment of your business&#8217;s readiness for AI implementation.</strong><br />
</strong></strong></h2>		</div>

		<button	class="btn btn--color-infinum btn--size-small btn--width-default btn__icon-position--right card-simple__btn js-block-card-btn js-card-simple-link"
	data-id="es-116"
	 tabindex='-1'>
		<div class="btn__inner">
					<div	class='typography typography--size-none js-typography btn__label'
	data-id='es-117'
	>
	Learn more </div>		
		<i
	class="icon btn__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='arrow-right-16' data-id='es-118'>
	<svg fill='none' height='16' viewBox='0 0 17 16' width='17' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><g stroke='currentColor' stroke-width='2'><path d='m.5 7.99999 14 .00001'/><path d='m9.23352 2.7251 5.97848 5.97852'/><path d='m9.23352 13.2744 5.97848-5.9785'/></g></svg></i>	</div>
	</button>	</div>
</a>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-122"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-120">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-121'
	>
	A recommendation system for recipes</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-125"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-123">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-124'
	>
	Besides being a companion app for controlling Philips’ smart kitchen appliances, an integral part of the NutriU app is to provide a platform for users to add, browse, and share recipes.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-128"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-126">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-127'
	>
	With the previous solution, the user would open the home screen or the search screen, and the app would show them a certain number of recipes from the database.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-131"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-129">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-130'
	>
	What criteria were the recipes being shown based on? They were sorted according to simple, manually done criteria and then displayed top-to-bottom.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-134"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-132">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-133'
	>
	There were a couple of shortfalls to this approach:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-137"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-135">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-136'
	>
	<li>All users would see exactly the same recipes (they are not personalized), therefore are not particularly interesting to the users</li><li>The food recipe app didn’t use the data about user interaction with the app and the recipes they were looking at in any way</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-140"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-138">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-139'
	>
	They were deteriorating the user experience, hence there was a need for a recommendation system. It would be implemented as REST API in Python using the famous Flask library.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-143"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-141">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-142'
	>
	Philips had a couple of demands for the recommendation system:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-146"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-144">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-145'
	>
	<li>Users should only get recommendations for recipes they had not seen before</li><li>Predictions of recommendations would have to be dynamic and include users’ recent actions, which means these recommendations could not be precalculated</li><li>Updates of the recommender model would have to be frequent and should not interrupt REST API in any way</li></ul></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-151"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-149"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-150">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/08/NutriU-in-article-visual-1-min-1400x644.webp				media='(max-width: 699px)'
				type=image/webp								height="644"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2023/08/NutriU-in-article-visual-1-min-2400x1105.webp				media='(max-width: 1199px)'
				type=image/webp								height="1105"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2023/08/NutriU-in-article-visual-1-min.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1252"
															width="2720"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-238"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-152">
	

</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-155"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-153">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-154'
	>
	Its majesty, data</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-158"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-156">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-157'
	>
	For building a recommendation system, we needed its majesty, data. We were lucky that the NutriU already had an implemented collection of data about user interactions with the app-relevant recommendation system, such as recipe views, as well as recipe likes and comments etc.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-161"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-159">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-160'
	>
	We focused on making use of the data on recipe views. The amount of collected data for this interaction was more ample than for other interactions. Take into consideration that NutriU doesn’t have a “real” rating system, thus we only had implicit user feedback to work with.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-164"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-162">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-163'
	>
	NutriU used the Firebase platform for event tracking and analytics, so user interaction data was stored in BigQuery, the service which enables fast and interactive analysis of massive datasets. It also enables easy integration with Python’s most popular library for data analysis and manipulation–Pandas.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-167"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-165">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-166'
	>
	Acceptable execution time?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-170"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-168">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-169'
	>
	However, this is when we stumbled upon our first obstacle. Because we had to calculate recommendations dynamically, we had to fetch the data about user interactions every time anew. Although BigQuery runs blazing-fast SQL queries on gigabytes to petabytes of data, execution time for smaller queries is not that fast.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-173"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-171">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-172'
	>
	Let’s say you have 1 million records in your database. In that case, query execution time is around 2-3 seconds, which is amazing. However, if you have a lot less data, e.g. a hundred of records, query execution remains around 2-3 seconds. Not that fast anymore.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-176"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-174">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-175'
	>
	In fact, this pace was not acceptable for our recommender. Typically, using BigQuery as a main database in a web application is not suggested. So we had to build additional database which would regularly pull a relevant subset of data from BigQuery and communicate with REST API.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-179"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-177">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-178'
	>
	For teams dealing with this at scale, <strong><a href="https://infinum.com/blog/scaling-ai-with-databricks/">a lakehouse approach with Databricks</a></strong> offers a more integrated path by co-locating data, pipelines, and retrieval on a single, governed platform.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-182"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-180">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-181'
	>
	Lightning-fast recommendation calculus</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-185"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-183">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-184'
	>
	There are several common approaches used for building a recommender system, the most popular being:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-188"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-186">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-187'
	>
	<li>Collaborative filtering: This approach uses collaborative information, i.e. implicit or explicit user interaction with items (such as recipes viewed or liked). It doesn’t use information about the actual items or users.</li><li>Content-based approach: This approach works purely on user’s or item’s characteristics. They completely ignore interactions between users and items.</li><li>Hybrid approach: A combination of the previous two approaches.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-191"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-189">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-190'
	>
	There are also other, more advanced approaches, such as matrix factorization and sequential models created with deep learning. Taking each approach into consideration, the team finally settled on collaborative filtering for multiple reasons.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-194"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-192">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-193'
	>
	For starters, collaborative filtering is very interpretable, making it simple to explain why some recipe was recommended. It is based on the principle: “If users A and B liked recipe X, and user B likes recipe Y, there is a huge chance that user A will also like the recipe Y”. Furthermore, other approaches require a lot more work fine-tuning the models for predicting meaningful recommendations, while collaborative filtering works on the plug &amp; play principle.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-197"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-195">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-196'
	>
	We implemented collaborative filtering with an <a href="https://github.com/benfred/implicit">implicit</a> library. This amazing library has a simple interface, comes with support for implicit feedback datasets and all its operations and routines are vectorized and multi-threaded, so recommendation calculus is lightning fast.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-200"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-198">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-199'
	>
	However, the collaborative filtering method will not yield quality recommendations for cold-start users, i.e. the users who have had no previous interaction with recipes. To them, the app will recommend the recipes with the most views.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-203"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-201">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-202'
	>
	Putting theory into practice</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-206"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-204">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-205'
	>
	The recommender system is implemented by microservice architecture. It is comprised of two components:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-209"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-207">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-208'
	>
	<li>Scheduler</li><li>Rest API</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-212"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-210">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-211'
	>
	Collaborative filtering algorithm requires calculation of similarity matrix which is then used to produce recommendations. Similarity matrix calculation is a time-consuming task, which is why we decided to create a scheduled task which will execute the whole process of similarity matrix calculation:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-215"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-213">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-214'
	>
	<li>pull new data from BigQuery</li><li>store BigQuery data into PostgreSQL</li><li>use stored data to create similarity matrix</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-218"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-216">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-217'
	>
	Rest API component responds to a user request for recommendations and returns the recommended recipes. We already mentioned that the model needs to be frequently updated without interruptions. Communication between the two components is achieved with Amazon’s S3 buckets.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-221"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-219">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-220'
	>
	The scheduler component generates the similarity matrix and saves it, while the Rest API component loads the generated matrix into the memory once it is generated for the faster serving of recommendations.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-224"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-222">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-223'
	>
	To avoid interruptions, Rest API runs a background job for loading new similarity matrix and switches it with the current one. We ensured that there could be only one job run in parallel.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-227"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-225">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-226'
	>
	We benchmarked recommendation request execution time for a cold-start user and for a non cold-start user. Specifically, we picked the user with the most interactions with the app. Benchmarks were created with 2,4 GHz Intel Core i7 processor:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-230"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-228">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-229'
	>
	<li>Execution time for cold start user is 0.1 s</li><li>Execution time for non-cold start user is 0.05 s</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-233"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-231">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-232'
	>
	Does the new NutriU work better?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-236"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-234">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-235'
	>
	To see if our recommender beats the previous solution, we conducted A/B testing experiments. Here are the results for Android.<br></p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-241"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-239"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-240">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/08/NutriU-in-article-visual-3-min-1400x540.webp				media='(max-width: 699px)'
				type=image/webp								height="540"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2023/08/NutriU-in-article-visual-3-min-2400x926.webp				media='(max-width: 1199px)'
				type=image/webp								height="926"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2023/08/NutriU-in-article-visual-3-min.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1050"
															width="2720"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-244"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-242"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-243">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/08/NutriU-in-article-visual-4-min-1400x487.webp				media='(max-width: 699px)'
				type=image/webp								height="487"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2023/08/NutriU-in-article-visual-4-min-2400x836.webp				media='(max-width: 1199px)'
				type=image/webp								height="836"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2023/08/NutriU-in-article-visual-4-min.webp"
					class="image__img block-media__image-img"
					alt=""
										height="947"
															width="2720"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-250"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-245">
	

</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-248"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-246">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-247'
	>
	The following are the results for the iOS platform.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-253"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-251"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-252">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/08/NutriU-in-article-visual-5-min-1400x540.webp				media='(max-width: 699px)'
				type=image/webp								height="540"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2023/08/NutriU-in-article-visual-5-min-2400x926.webp				media='(max-width: 1199px)'
				type=image/webp								height="926"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2023/08/NutriU-in-article-visual-5-min.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1050"
															width="2720"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-256"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-254"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-255">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/08/NutriU-in-article-visual-6-min-1400x487.webp				media='(max-width: 699px)'
				type=image/webp								height="487"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2023/08/NutriU-in-article-visual-6-min-2400x836.webp				media='(max-width: 1199px)'
				type=image/webp								height="836"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2023/08/NutriU-in-article-visual-6-min.webp"
					class="image__img block-media__image-img"
					alt=""
										height="947"
															width="2720"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-274"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-257">
	

</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-260"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-258">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-259'
	>
	Experiment results are crystal clear. Our proposed variant performed 168% better for the search screen, and 70% better for the home screen.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-263"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-261">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-262'
	>
	A simple choice for an efficient result</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-266"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-264">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-265'
	>
	The solution described in this post uses one of the simplest algorithms for recommendations. Yet, it achieved impressive results in A/B experiments with additional gains in the interpretability of recommendations and extremely fast execution.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-269"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-267">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-268'
	>
	The intended takeaway from this blog post is that with careful and structured implementation, it is possible to significantly improve users engagement by using simple algorithms and create the foundation for future, more complex improvements.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-272"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-270">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-271'
	>
	<em>If you&#8217;d like to learn how else we can utilize machine learning and artificial intelligence to help you achieve your business goals, check out our <a href="https://infinum.com/ai-business-solutions/" target="_blank" rel="noreferrer noopener">AI business solutions</a> page. </em></p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/building-a-recommendation-system-for-a-culinary-app/">Building a Tailored Recommendation System for Philips NutriU</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>7874https://infinum.com/uploads/2019/02/fast-license-plate-concealment-with-deep-learning-0.webp</url>
				</image>
				<title>Fast License Plate Concealment with Deep Learning</title>
				<link>https://infinum.com/blog/fast-license-plate-concealment-with-deep-learning/</link>
				<pubDate>Fri, 01 Feb 2019 16:00:00 +0000</pubDate>
				<dc:creator>Marin Krešo</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/fast-license-plate-concealment-with-deep-learning/</guid>
				<description>
					<![CDATA[<p>It is possible to build a license plate concealment system that is both fast and precise, and can work equally well on all cameras. </p>
<p>The post <a href="https://infinum.com/blog/fast-license-plate-concealment-with-deep-learning/">Fast License Plate Concealment with Deep Learning</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-405"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-275">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-278"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-276">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-277'
	>
	As technology advances, we have new and improved ways of dealing with various problems. One example would be the use of high-resolution cameras in traffic. They can be placed on congestion points for the purpose of traffic reports (so commuters would know which places to avoid on their way to work).</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-281"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-279">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-280'
	>
	Also, we can monitor car flows for making a decision about the development of future roads, and use them for quick reactions in case of accidents or similar problems. These tasks are a lot easier if cameras have high resolution. But with that improvement, often we have a picture so clean that we can read license plates of the cars passing by.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-284"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-282">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-283'
	>
	Our task was to perform the <strong>detection and concealment of such readable license plates</strong>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-287"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-285">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-286'
	>
	Why conceal license plates?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-290"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-288">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-289'
	>
	Besides running from police, one couldn’t think of a good reason for concealing license plate number. Well, that was maybe the case, but lately, there has been a lot of concern regarding the private data of individuals.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-293"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-291">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-292'
	>
	The main drive of this is the introduction of <strong>GDPR</strong>, a set of European Union regulations that govern how companies have to manage personal data. GDPR covers any data that can be used to identify a person, even indirectly. License plate numbers are personal information under GDPR because you can theoretically identify the owner of the car if you know their license plate number.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-296"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-294">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-295'
	>
	This could be exploited to track someone&#8217;s whereabouts, so we need an efficient way to conceal readable license plates. To conceal them, we must first be able to detect them. This is a complex task due to the continuous flow of cars passing by the cameras.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-299"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-297">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-298'
	>
	Because of its complexity and tediousness, this task is not suitable for humans, but it is perfect for a machine system. A system for this task needs to be fast, precise, and generalized to do the same thing on all cameras.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-302"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-300">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-301'
	>
	How do we build such a system? Well, the answer is a technology called Deep Learning. Because of simplified ways to collect huge amounts of data, machines that can perform fast computations, and advances in the field of AI, Deep Learning today is the defacto state-of-the-art approach for Computer Vision.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-305"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-303">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-304'
	>
	Overview of the system</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-308"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-306">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-307'
	>
	The system is made up of three major parts:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-311"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-309">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-310'
	>
	<li>Object detection</li><li>Landmark detection</li><li>REST API</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-314"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-312"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-313">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2019/01/fast-license-plate-concealment-with-deep-learning-1-1400x726.webp				media='(max-width: 699px)'
				type=image/webp								height="726"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2019/01/fast-license-plate-concealment-with-deep-learning-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="731"
															width="1410"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			system overview		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-317"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-315">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-316'
	>
	Object detection</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-320"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-318">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-319'
	>
	First, we want to detect all license plates in one frame (one frame could contain multiple cars). The output here is a bounding box of detected license plates for concealment. We have around 13.000 labeled images for this task.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-323"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-321"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-322">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2022/03/shrine-s320190107-23397-hiw06d20190107-23397-ba7h0z20190107-23397-1s941r5.webp"
					class="image__img block-media__image-img"
					alt=""
										height="366"
															width="705"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			Distribution of license plates on frames		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-326"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-324">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-325'
	>
	We could build the model from scratch, but there are other already trained models on similar tasks which we could use. For this, we use the Tensorflow Object Detection API, because it makes it easy to construct, train and deploy object detection models. This API also has a number of different trained models; therefore we can choose the best suitable model for our needs. These models are not trained for detecting license plates, but we can use them and fine-tune them on our dataset for our specific task Transfer learning.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-329"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-327">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-328'
	>
	We mentioned that our system must be both fast and precise, so we have a <strong>trade-off between speed and accuracy</strong>. The most precise model for object detection is <em>Faster R-CNN</em> model, but the fastest one is <em>SSD MobileNet</em> (source). After experiments with both, we chose <em>SSD MobileNet</em>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-332"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-330">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-331'
	>
	Although <em>Faster R-CNN</em> has magnificent accuracy, this model is very slow. Cameras send frames every few seconds, and we must process the images and detect all license plates in a short period of time so our system would be efficient. With advanced hardware, this is achievable but also very expensive. Also, it is not scalable – If we add more cameras, the cost will increase rapidly.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-335"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-333">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-334'
	>
	<em>SSD MobileNet</em> is a lot faster than <em>Faster R-CNN</em> but it has lower accuracy. <strong>Is there a way we could improve accuracy of our system with <em>SSD MobileNet</em> as an object detection model, but without losing too much speed?</strong> Well, this is the task of the next part of our system.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-338"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-336">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-337'
	>
	Landmark detection</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-341"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-339">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-340'
	>
	The task of this model is to give us finer and better detections of license plates. The idea is simple: For each detection in a frame we send a bounding box of detected license plates to a landmark detection model to find corners of a specific license plate.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-344"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-342">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-343'
	>
	We built this model from scratch in KERAS with Tensorflow as backend. By using a Convolutional Neural Network (CNN) that takes an image with 100×100 size of car with license plate as input, and outputs x,y coordinates for all 4 corners of license plate.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-347"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-345">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-346'
	>
	The model was trained on 20.000 images of license plates and annotations of the license plate corners. <strong>By detecting corners, we have a much better approximation of license plate location, and thus, improved precision</strong>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-350"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-348">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-349'
	>
	The model is not complex (for CNN) – we set up simple neural network architecture with two convolutional layers followed by two fully connected dense layers and an output layer (the model has 3 million trainable parameters), therefore its predictions are very fast (3 ms per license plate on 2,4 GHz Intel Core i7) and have a tiny effect on the speed of detections, so this gives us precisely what we want.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-353"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-351">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-352'
	>
	<strong>But with this model, we gain another huge advantage</strong>. Object detection models always output rectangular shapes of their detections. Because of the angle of the camera watching the traffic, license plates on the frames don’t have a proper rectangular form. With corner detection, we can get much finer detection and practically get some quadrangular shapes of the detected license plates.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-356"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-354"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-355">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2022/03/shrine-s320190110-29139-183q2kp20190110-29139-ijssc20190110-29139-gllw64-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="438"
															width="534"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			Comparison of the object (in yellow) and landmark (in red) detection		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-359"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-357">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-358'
	>
	It is important to notice that we expand the bounding box of detected license plates because we want a bigger context and more information for our landmark detection model to achieve better generalization.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-362"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-360">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-361'
	>
	Another reason is mentioned lower accuracy of <em>SSD MobileNet</em> – this model sometime returns a bounding box that doesn’t cover the whole license plate.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-365"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-363">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-364'
	>
	REST API</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-368"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-366">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-367'
	>
	The purpose of the REST API is coordination between cameras and deep learning models for detection. The app takes requests (video streams frame by frame) from clients (traffic cameras) and delegates them to the previously mentioned modules. After detection and blurring part frame is sent back to the client. <strong>We got an additional significant boost in the computational speed, by building a Tensorflow package from the source code</strong>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-371"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-369">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-370'
	>
	Summary &amp; results</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-374"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-372">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-373'
	>
	To summarize the system, this is what it all looks like:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-378"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--black block-bullet__bullet" data-id="es-375">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-376'
	>
	1</p>	<div class="bullet__content">
		<p	class='typography typography--size-16-text-roman js-typography bullet__paragraph'
	data-id='es-377'
	>
	A camera records the road and every few seconds sends a frame to a web interface of our system.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-382"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--black block-bullet__bullet" data-id="es-379">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-380'
	>
	2</p>	<div class="bullet__content">
		<p	class='typography typography--size-16-text-roman js-typography bullet__paragraph'
	data-id='es-381'
	>
	Each frame is preprocessed and then sent to an object detection model for recognizing all license plates in the frame.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-386"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--black block-bullet__bullet" data-id="es-383">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-384'
	>
	3</p>	<div class="bullet__content">
		<p	class='typography typography--size-16-text-roman js-typography bullet__paragraph'
	data-id='es-385'
	>
	An expanded bounding box of each detected license plate is sent to the landmark detection model, which returns predictions of each of the four corners of a given license plate.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-390"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--black block-bullet__bullet" data-id="es-387">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-388'
	>
	4</p>	<div class="bullet__content">
		<p	class='typography typography--size-16-text-roman js-typography bullet__paragraph'
	data-id='es-389'
	>
	For each detected license plate in the frame, we blur the part that is between corners.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-394"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--black block-bullet__bullet" data-id="es-391">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-392'
	>
	5</p>	<div class="bullet__content">
		<p	class='typography typography--size-16-text-roman js-typography bullet__paragraph'
	data-id='es-393'
	>
	Frame with blurred license plates gets returned to the client.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-397"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-395"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-396">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2019/02/fast-license-plate-concealment-with-deep-learning-4.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1410"
															width="980"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			License plate detection pipeline		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-400"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-398">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-399'
	>
	In this blog post we have shown that it is possible to build a license plate concealment system that is both fast and precise. Furthermore, the system is generalized to work equally well on all cameras. All this is possible with emerging deep learning techniques.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-403"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-401">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-402'
	>
	Need help with your Machine Learning projects? <a href="https://infinum.com/contact/">Get in touch</a>, we’d love to help with your challenge.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/fast-license-plate-concealment-with-deep-learning/">Fast License Plate Concealment with Deep Learning</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>