title: How to match the color models of BufferedImage and Mat?
body: <p>I'm trying to convert <a href="http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html" rel="nofollow noreferrer"><code>BufferedImage</code></a> to <a href="http://docs.opencv.org/doc/tutorials/core/mat_the_basic_image_container/mat_the_basic_image_container.html" rel="nofollow noreferrer"><code>Mat</code></a> for a large set of images with different file types downloaded from the internet. Because I am scraping the images from websites, I have no control over the file formats. I can easily load them to <code>BufferedImage</code> without knowing the format, but to convert them to <code>Mat</code>, I need to know the image type. Unfortunately, there doesn't seem to be a nice correspondence between <code>CvType</code> and <code>BufferedImage</code> types. </p>
  
  <p><code>CvType</code> represents image types with the format <code>CV_&lt;bit-depth&gt;{U|S|F}C&lt;number_of_channels&gt;</code> where <code>U</code> is unsigned char, <code>S</code> is signed char, and <code>F</code> is float. </p>
  
  <p><code>BufferedImage</code> types have more variety in the representation including a symmetrical channels (<a href="http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html#TYPE_4BYTE_ABGR" rel="nofollow noreferrer"><code>TYPE_4BYTE_ABGR</code></a>), varying numbers of bits (<a href="http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html#TYPE_BYTE_BINARY" rel="nofollow noreferrer"><code>TYPE_BYTE_BINARY</code></a>), and whatever an indexed byte image is (<a href="http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html#TYPE_BYTE_INDEXED" rel="nofollow noreferrer"><code>TYPE_BYTE_INDEXED</code></a>).</p>
  
  <p>Based on the documentation, I tried to complete my own correspondence.</p>
  
  <pre><code>BufferedImage imgBuffer = ImageIO.read(new File("example.gif"));
  
  //Save file as reference
  File outputfile = new File("temp/image.png");
  ImageIO.write(imgBuffer, "png", outputfile);
  
  //My correspondance
  int curCVtype = -1;
  switch (imgBuffer.getType()) {
  case BufferedImage.TYPE_3BYTE_BGR:
      curCVtype = CvType.CV_8UC3;
      break;
  case BufferedImage.TYPE_BYTE_GRAY:
      curCVtype = CvType.CV_8UC1;
      break;
  case BufferedImage.TYPE_INT_BGR:
  case BufferedImage.TYPE_INT_RGB:
      curCVtype = CvType.CV_8SC3;
      break;
  case BufferedImage.TYPE_INT_ARGB:
  case BufferedImage.TYPE_INT_ARGB_PRE:
      curCVtype = CvType.CV_8SC4;
      break;
  default:
  //  The types not handled by my correspondence
  //                  BufferedImage.TYPE_BYTE_BINARY;
  //                  BufferedImage.TYPE_USHORT_GRAY;
  //                  BufferedImage.TYPE_4BYTE_ABGR;
  //                  BufferedImage.TYPE_4BYTE_ABGR_PRE;
  //                  BufferedImage.TYPE_BYTE_INDEXED;
  //                  BufferedImage.TYPE_CUSTOM;
  
      System.out.println("Unsupported format:" + imgBuffer.getType());
      //Here I choose a default type
      curCVtype = CvType.CV_8SC3;
  }
  
  //Convert to Mat
  byte[] pixels = ((DataBufferByte) imgBuffer.getRaster().getDataBuffer()).getData();
  Mat img = new Mat(imgBuffer.getHeight(), imgBuffer.getWidth(), curCVtype);
  img.put(0, 0, pixels);
  
  //Write the output to compare
  Imgcodecs.imwrite("temp/image_mat.png", img);
  </code></pre>
  
  <h2>Questions</h2>
  
  <ol>
  <li>Am I going about this correctly? Or is there a better approach? </li>
  <li>What are the correct correspondences for the types that are in my default case? </li>
  </ol>
  
  <h2>Examples</h2>
  
  <p>Input <br> 
  <a href="https://i.stack.imgur.com/ZXwsa.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ZXwsa.gif" alt="Input example gif"></a></p>
  
  <p>Converted to PNG by <code>BufferedImage</code> <br> 
  <a href="https://i.stack.imgur.com/fE2Su.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/fE2Su.png" alt="Reference BufferedImage"></a>   </p>
  
  <p>Output PNG after conversion to Mat. <code>BufferedImage</code> type was<code>TYPE_BYTE_INDEXED</code> converted to <code>CvType.CV_8SC3</code> <br> 
  <a href="https://i.stack.imgur.com/AuoJV.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/AuoJV.png" alt="Mat output"></a> </p>
  
  <p>Output PNG after conversion to Mat. <code>BufferedImage</code> type was<code>TYPE_BYTE_INDEXED</code> converted to <code>CvType.CV_8UC3</code> <br> 
  <a href="https://i.stack.imgur.com/lRmJB.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/lRmJB.png" alt="Mat output"></a></p>
  
  <h2>Resources:</h2>
  
  <p>My starting code came from <a href="https://stackoverflow.com/questions/14958643/converting-bufferedimage-to-mat-in-opencv">Converting BufferedImage to Mat in opencv</a> . </p>
  
  <p>What I know about CvTypes came from <a href="https://stackoverflow.com/questions/13428689/whats-the-difference-between-cvtype-values-in-opencv">What&#39;s the difference between cvtype values in OPENCV?</a> .</p>