title: Serializing Face Features for recognition in DLIB
body: <p>I am writing a dlib code to do face recognition on 1 to 1 basis.</p>
  
  <p>I followed the code sample in <a href="http://dlib.net/dnn_face_recognition_ex.cpp.html" rel="nofollow noreferrer">dlib samples</a> and did the following:</p>
  
  <pre><code>std::vector&lt;matrix&lt;rgb_pixel&gt;&gt; faces;
  for (auto face : detector(img1))
  {
      auto shape = sp(img1, face);
      matrix&lt;rgb_pixel&gt; face_chip;
      extract_image_chip(img1, get_face_chip_details(shape, 150, 0.25), face_chip);
      faces.push_back(move(face_chip));
  }
  </code></pre>
  
  <p>this is for the first image and then did the same for the second image:</p>
  
  <pre><code>for (auto face : detector(img2))
  {
      auto shape = sp(img2, face);
      matrix&lt;rgb_pixel&gt; face_chip;
      extract_image_chip(img2, get_face_chip_details(shape, 150, 0.25), face_chip);
      faces.push_back(move(face_chip));
  }
  </code></pre>
  
  <p>then i continue  as per the mentioned link:</p>
  
  <pre><code>std::vector&lt;matrix&lt;float, 0, 1&gt;&gt; face_descriptors = net(faces);
  std::vector&lt;sample_pair&gt; edges;
  for (size_t i = 0; i &lt; face_descriptors.size(); ++i)
  {
       for (size_t j = i; j &lt; face_descriptors.size(); ++j)
       {
            if (length(face_descriptors[i] - face_descriptors[j]) &lt; threshold)
                edges.push_back(sample_pair(i, j));
       }
   }
   std::vector&lt;unsigned long&gt; labels;
   const int num_clusters = chinese_whispers(edges, labels);
  //etc
  </code></pre>
  
  <p>and now comes my question. img1 is an image already available to the code that is read when i need to match a specific person. (ie if I want to mach personX, img1 is read using </p>
  
  <pre><code>load_image(img1, "personX.jpg");
  </code></pre>
  
  <p>Instead of having the image saved, i was trying to save the features and load them to reduce the time spent the extraction of features. so what I did is I moved the first for loop at a different function (enrollment like)  and made it something like this:</p>
  
  <pre><code>std::vector&lt;matrix&lt;rgb_pixel&gt;&gt; faces;
  for (auto face : detector(img1))
  {
      auto shape = sp(img1, face);
      matrix&lt;rgb_pixel&gt; face_chip;
      extract_image_chip(img1, get_face_chip_details(shape, 150, 0.25), face_chip);
      serialize("personX.dat") &lt;&lt;face_chip;
  }
  </code></pre>
  
  <p>then at the recognition instead of the loop i used</p>
  
  <pre><code>matrix&lt;rgb_pixel&gt; face_chip;
  deserialize("personX.dat")&gt;&gt;face_chip;            
  faces.push_back(move(face_chip));
  </code></pre>
  
  <p>and the rest of the code from the extraction of img2 onward remained the same. the code compiled. But during execution when i reach the recognition i end up with the following error:</p>
  
  <p>**************************** FATAL ERROR DETECTED ****************************</p>
  
  <p>Error detected at line 216.
  Error detected in file /usr/local/include/dlib/dnn/input.h.
  Error detected in function void dlib::input_rgb_image_sized::to_tensor(forward_iterator, forward_iterator, dlib::resizable_tensor&amp;) const [with forward_iterator = __gnu_cxx::__normal_iterator*, std::vector > >; long unsigned int NR = 150ul; long unsigned int NC = 150ul].</p>
  
  <p>Failing expression was i->nr()==NR &amp;&amp; i->nc()==NC    input_rgb_image_sized::to_tensor()</p>
  
  <p>All input images must have 150 rows and 150 columns, but we got one with 0 rows and 0 columns.</p>
  
  <p>Is there something wrong with the serialization / de-serialization? or should i do writing the features to a file with another method?</p>
  
  <p>code for the full funtion: </p>
  
  <pre><code>try
  {
      load_image(img1, check_image);
  }
  catch (...)
  {
      cout&lt;&lt;"Name: "&lt;&lt;uname&lt;&lt;" doesn't exist"&lt;&lt;endl;
      return;
  }
  
  else
  {
      QElapsedTimer timer;
      timer.start();
  
  
      dlib::assign_image(img2, dlib::cv_image&lt;bgr_pixel&gt;(colorImage));
      std::vector&lt;matrix&lt;rgb_pixel&gt;&gt; faces;
  
      for (auto face : detector(img1))
      {
          auto shape = sp(img1, face);
          matrix&lt;rgb_pixel&gt; face_chip;
          extract_image_chip(img1, get_face_chip_details(shape, 150, 0.25), face_chip);
          faces.push_back(move(face_chip));
  //                serialize("out.dat")&lt;&lt;face_chip;   //used whin i dont need to read image
      }
  
  //            matrix&lt;rgb_pixel&gt; face_chip; //used whin i dont need to read image
  //            deserialize("out.dat")&gt;&gt;face_chip; //used whin i dont need to read image
  //            faces.push_back(move(face_chip)); //used whin i dont need to read image
  
      cout&lt;&lt;"Time to extract features for enroled image: "&lt;&lt;timer.elapsed()&lt;&lt;endl;
      timer.restart();
  
      for (auto face : detector(img2))
      {
          auto shape = sp(img2, face);
          matrix&lt;rgb_pixel&gt; face_chip;
          extract_image_chip(img2, get_face_chip_details(shape, 150, 0.25), face_chip);
          faces.push_back(move(face_chip));
      }
  
      cout&lt;&lt;"Time to extract features for new image: "&lt;&lt;timer.elapsed()&lt;&lt;endl;
      timer.restart();
  
      if (faces.size() &lt; 2)
      {
          cout&lt;&lt;"No Face"&lt;&lt;endl;
      }
  
      else
      {
          std::vector&lt;matrix&lt;float, 0, 1&gt;&gt; face_descriptors = net(faces);
          std::vector&lt;sample_pair&gt; edges;
          for (size_t i = 0; i &lt; face_descriptors.size(); ++i)
          {
              for (size_t j = i; j &lt; face_descriptors.size(); ++j)
              {
                  if (length(face_descriptors[i] - face_descriptors[j]) &lt; threshold)
                      edges.push_back(sample_pair(i, j));
              }
          }
          std::vector&lt;unsigned long&gt; labels;
          const int num_clusters = chinese_whispers(edges, labels);
  
          if (num_clusters == 1)
          {
              cout&lt;&lt;"Recognized"&lt;&lt;endl;
          }
          else
          {
                      cout&lt;&lt;"Faces don't match";
          }
      }
  
      cout&lt;&lt;"Needed time is: "&lt;&lt;timer.elapsed()&lt;&lt;" ms"&lt;&lt;endl;
  }
  </code></pre>