<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Konstantinos Mavrodis</title>
    <description>The latest articles on DEV Community by Konstantinos Mavrodis (@kmavrodis).</description>
    <link>https://dev.to/kmavrodis</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F38212%2Fba7d8af2-9aa6-477c-99ce-7ef729c5c657.jpeg</url>
      <title>DEV Community: Konstantinos Mavrodis</title>
      <link>https://dev.to/kmavrodis</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kmavrodis"/>
    <language>en</language>
    <item>
      <title>Going through 10,000 pictures in 30 seconds</title>
      <dc:creator>Konstantinos Mavrodis</dc:creator>
      <pubDate>Tue, 21 Nov 2017 11:03:27 +0000</pubDate>
      <link>https://dev.to/kmavrodis/going-through-10000-pictures-in-30-seconds-ad8</link>
      <guid>https://dev.to/kmavrodis/going-through-10000-pictures-in-30-seconds-ad8</guid>
      <description>

&lt;p&gt;For the last 5 years I have been studying Electrical and Computer Engineering and it has changed me in so many ways. I made new friends, met interesting people and worked and learned a lot. Long story short, after countless early-morning classes and late-night drinks, last week I graduated!&lt;/p&gt;

&lt;p&gt;And it was great! The university held a big graduation ceremony with all these important academic people, relatives, friends, and more than 90 graduating students. I like these ceremonies. Everyone seems so happy. What better way to hold on to this happiness from capturing it in photos? Professional photographers, of course, realize it and are always there. Oh boy, there are always a lot of them.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j-9WMlSo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/hQ2DT7O.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j-9WMlSo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/hQ2DT7O.jpg" alt="Alt text" title="Photographer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The way this works is dozens of photographers take thousands of photos of happy graduating students and their families. They later upload low resolution copies of them on a website and students can check them out, or even buy some. But there is a problem... There are far too many photos and they are not tagged.&lt;/p&gt;

&lt;p&gt;Take a look in the photos of &lt;a href="https://www.fotomada.gr/events/view/1545"&gt;my graduation&lt;/a&gt;. We are talking about 436 pages with 24 pictures each, totaling to about 10,400 photos. The worst part is, that the only way to find a specific person is to go through all of those photos manually. A process that with a rough estimation would take up to three hours. I mean, I am not the busiest man in the world, but it seems like a lot of time for picking a couple of photos.&lt;/p&gt;

&lt;p&gt;I made it through the 20th page and was already bored. There had to be another way, I figured. Besides, if you have to do the same thing more than once, a computer can do it better than you. So, I came up with a simple idea. What if I wrote a script to scrape all the photos and pass them through some sort of algorithm that could detect my face and return only the photos I am in. Theoretically it should work and theoretically it should take me less than three hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  Downloading photos
&lt;/h2&gt;

&lt;p&gt;As I already mentioned, the website I am targeting is organized in pages and every page contains 24 photos. What I need is a script that can iterate through all these pages and download the photos.&lt;/p&gt;

&lt;p&gt;At first I intended to write everything in Python but after realizing how easy it would be to write a simple bash script leveraging the power of wget, I thought, why not do this instead. So here it is:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;1..436&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;do
  &lt;/span&gt;wget &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-l1&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt;.jpg https://www.example.com/events/view/1545?page&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There is not much to it to be honest. The script iterates through every one of the 436 pages and runs a simple wget command to download all jpg images. Notice that it uses the wget's retrieval option, meaning that wget crawls the webpage following links and directories. You can learn more about this interesting algorithm &lt;a href="https://www.gnu.org/software/wget/manual/html_node/Recursive-Download.html#Recursive-Download"&gt;here&lt;/a&gt;. This way wget won't just download the thumbnails of the pictures but also the original ones. Some extra pixels will be crucial for the [spoiler] machine learning algorithm I intend to use later on [/spoiler].&lt;/p&gt;

&lt;p&gt;After its execution, the script has filled a folder with more or less 10,400 photos ready to be analyzed. Below is a small portion of the 10,400 images that were scrapped from the website.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VakO6uz1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/rr3a5in14m5rtnfu5qjn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VakO6uz1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/rr3a5in14m5rtnfu5qjn.png" alt="Alt text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Face recognition
&lt;/h2&gt;

&lt;p&gt;The only thing missing now is finding a way to detect my face across all these images. Good thing we have machine learning for that! There are pre-trained models and ready to go libraries all over the place, that you can use on your project and give it magical skills.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ageitgey/face_recognition"&gt;Face recognition&lt;/a&gt; is an excellent open-source python library that can do just that and is advertised to have an accuracy of 99.38%, while working on top of the famous &lt;a href="http://dlib.net/"&gt;dlib&lt;/a&gt; library. It basically provides access to a set of algorithms and operates as black-box allowing the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Find faces in pictures&lt;/li&gt;
&lt;li&gt;Manipulate facial features&lt;/li&gt;
&lt;li&gt;Identify people using their faces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without diving into too much detail, I' ll try to explain how the system works, so it hopefully won't be a black box anymore. In order to find faces, the algorithm converts the picture to black and white, intending to deal with just brightness and not color. By drawing small vectors of how brightness changes (gradients) it creates a new image consisting of features, which can now be compared to a set of pre-processed pictures of faces. If they are close, a face is detected.&lt;/p&gt;

&lt;p&gt;In order to identify a person, the algorithm searches in a database of already known people for the person who has the closest measurements to the new one. Machine learning (yeah... no deep learning, sorry, I know it's hot right now, but it's not the solution to everything) is used to make this classification with a linear &lt;a href="https://en.wikipedia.org/wiki/Support_vector_machine"&gt;SVM classifier&lt;/a&gt;. To learn more about this process I recommend reading a much more accurate and in-depth explanation by Adam Geitgey &lt;a href="https://medium.com/@ageitgey/machine-learning-is-fun-part-4-modern-face-recognition-with-deep-learning-c3cffc121d78"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Applying face recognition
&lt;/h2&gt;

&lt;p&gt;Back to the initial problem now. The idea is to use a single image of my face, preferably one from the graduation day, to train the face recognition library and then pass each one of the 10,400 photos through the algorithm, that will return those that I am in.&lt;/p&gt;

&lt;p&gt;My face was used for training:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XBnRbyvH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/av4rgh8redpi9hscc9my.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XBnRbyvH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/av4rgh8redpi9hscc9my.png" alt="Alt text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some photos contain several faces, so it is important to make sure that all of them are compared to mine. Finally, all photos of me are stored in a separate folder, so it will be easier to examine them later. The python code that realizes these can be found bellow.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#import face_recognition
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;shutil&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;copyfile&lt;/span&gt;

&lt;span class="c1"&gt;# Create an encoding of my facial features that can be compared to other faces
&lt;/span&gt;&lt;span class="n"&gt;picture_of_me&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;face_recognition&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load_image_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mavrodis.jpg"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;my_face_encoding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;face_recognition&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;face_encodings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;picture_of_me&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Iterate through all the 10,460 pictures
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10461&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Construct the picture name and print it
&lt;/span&gt;    &lt;span class="n"&gt;file_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zfill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;".jpg"&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Load this picture
&lt;/span&gt;    &lt;span class="n"&gt;new_picture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;face_recognition&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load_image_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Iterate through every face detected in the new picture
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;face_encoding&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;face_recognition&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;face_encodings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_picture&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

        &lt;span class="c1"&gt;# Run the algorithm of face comaprison for the detected face, with 0.5 tolerance
&lt;/span&gt;        &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;face_recognition&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compare_faces&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;my_face_encoding&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;face_encoding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Save the image to a seperate folder if there is a match
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;copyfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/home/deeplearning/Desktop/my_face/mavrodis/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's pretty much it! Notice on line 21, a specific value (0.5) is provided. This is the tolerance (or threshold) of the algorithm. Higher tolerance tells the algorithm to be less strict, while lower means the opposite. It does take some time to run, since it has to check all 10,000+ photos (but there is surely room for some parallelization).&lt;/p&gt;

&lt;p&gt;Some of the photos that were automatically detected:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0Fn4Cw9z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/95y3vs7gof9hl4ardyrp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0Fn4Cw9z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/95y3vs7gof9hl4ardyrp.png" alt="Alt text"&gt;&lt;/a&gt;&lt;br&gt;
Tada! This is a success!&lt;/p&gt;

&lt;p&gt;There are a couple of things we should notice. There are watermarks on the photos, but face recognition didn't have any problems with that. Moreover, the algorithm works great for group photos, or photos that the face is far away from the camera lens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accuracy
&lt;/h2&gt;

&lt;p&gt;About 160 pictures of me were detected using this algorithm. If you consider there were 90 students (90*160 = 14,400 pictures, some of which were group photos) it makes sense from a statistics point of view. However, I cannot provide a percentage of the accuracy, since that would require me going through each one of the original 10,400 photos, which is what I was intending to avoid to begin with.&lt;/p&gt;

&lt;p&gt;I can tell you that there are false positives (people ending up in my folder, without being me) and that there are probably false negatives (photos of me that didn't end up in my folder) but overall it seems that there are not many of those.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Now, this was fun! At least much more fun than going through all the photos manually. I think it took less time, too. Not to mention that all my friends asked me to run the script for their faces. I even did it for some parents that were there. Wouldn't it be nice to see something like this implemented on photo shops' websites?&lt;/p&gt;

&lt;p&gt;Bill Gates once said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I choose a lazy person to do a hard job. Because a lazy person will find an easy way to do it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you are the lazy person, give the hard job to a computer. It will save you time and effort.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thanks for reading! Now, the lazy person needs to find the money to buy some of those graduation photos. No Machine Learning for that, I guess...&lt;/p&gt;


</description>
      <category>python</category>
      <category>machinelearning</category>
      <category>facerecognition</category>
      <category>graduation</category>
    </item>
    <item>
      <title>Failing and how to master it</title>
      <dc:creator>Konstantinos Mavrodis</dc:creator>
      <pubDate>Sat, 21 Oct 2017 20:09:56 +0000</pubDate>
      <link>https://dev.to/kmavrodis/failing-and-how-to-master-it-5im</link>
      <guid>https://dev.to/kmavrodis/failing-and-how-to-master-it-5im</guid>
      <description>

&lt;p&gt;Yet another self-improvement article.&lt;/p&gt;

&lt;p&gt;Let’s get a couple of things straight at first. I’m not intending to say what is expected and embrace failure as a means of improvement. In fact, I strongly believe that &lt;strong&gt;failure sucks and should be avoided at all costs&lt;/strong&gt;. It is what stands between you and your coveted goals, what keeps you awake at night and what you are trying to persuade yourself not to fear of.&lt;/p&gt;

&lt;p&gt;The first thing you should have in mind while making an effort, whether it is a boring school project or the implementation of your crazy start-up idea, is how to succeed and succeeding means not failing. Success is what we are all looking for and gives meaning to our lives at the end of the day. Failure does not. While, success keeps the human machine running, failure breaks it and sends it to the garage. It sounds sad, but it’s true. No-one has ever fallen into depression because of succeeding. I can’t say the same about failures though.&lt;/p&gt;

&lt;p&gt;How to always succeed? Here is some advice: A wise man once said, if you cannot find a solution to a problem, find another problem. This a common tactic to always stay on top and avoid the consequences of failure. Someone could argue that it’s a lazy tactic or even an act of cowardice, but it’s not. It’s called pivoting and pivoting is a good thing. It keeps crazy-big technology companies crazy-big and researchers sane and always with a job.&lt;/p&gt;

&lt;p&gt;Here is some more advice: Let’s say you have a goal, a big goal, let’s say you want to set foot on Mars for the first time in history. It is a long shot and you know it. You are probably going to fail multiple times until you make it… or maybe not! You don’t get many chances, because failing means rocket explosions and people dying. So, what can you do? It’s simple really. You set smaller goals and by gaining minor victories one by one you reach your goal. If you reach a dead end, it’s okay, you can still find another way to the end or find another end, you just have to pivot!&lt;/p&gt;

&lt;p&gt;But failure happens. No matter how careful and prepared you are, sooner or later failure is going to be waiting for you at your front door. The rising question is what happens next? How can you handle failure in the best possible way and get the most out of it? Unfortunately, I don’t have a perfect answer, in fact I don’t believe there is one. What I do have for you, instead, are a couple of ideas that can and should make you the &lt;em&gt;winner at a losing game&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Failure is a dangerous situation and as such it should be dealt with composure and respect. Here is a thought: Failure is, also, a big opportunity. Let’s say you are in the process of implementing your big plan. You take one step at a time and as long as everything runs smoothly you are succeeding. However, you are not careful enough and something goes terribly wrong. All of a sudden, you are moving away from your goal, walking in a path that you hadn’t foreseen. Failure just got you out of your comfort zone, to a state you weren’t intending to be. Take advantage of the situation and rethink everything. Make a new plan and decide what are the advantages and the disadvantages that have been brought to the table. Study the disadvantages and take action to eliminate them. Once you’ve done that, you might end up with some useful benefits that were not expected at first and become once again a winner.&lt;/p&gt;

&lt;p&gt;I started this article preaching about how important it is to avoid failure and I’m going to end it this way. However, at this point I want to &lt;strong&gt;redefine failure&lt;/strong&gt;. I think it was made clear that any bad situation can be avoided or effectively treated, that’s why it’s not really a failure. Real failure doesn’t come when you make a mistake, or when you fall down. It happens when you give up and decide not to stand up again.&lt;/p&gt;

&lt;p&gt;They say that Thomas Edison made 1.000 attempts to successfully build the light bulb and when asked how it felt failing for 1.000 times, he replied “I didn’t fail 1.000 times, the light bulb was an invention that took 1.000 steps.”. He was right he would have failed only if he had given up. This is what you should be trying to avoid folks and keep in mind that &lt;em&gt;you will fail, only if YOU decide so&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;After all, mastering failure might mean not failing at all, or at least never giving up…&lt;/p&gt;


</description>
      <category>career</category>
      <category>selfimprovement</category>
      <category>failure</category>
    </item>
  </channel>
</rss>
