Optimizing Bayer16 -> RGB in Python
<p>I am reading a camera that gives me Bayer16 format (GRGB) and I wrote the following code in python to modify it from bayer16 to bayer8, and then use OpenCV to convert it to RGB:</p>

<pre><code>def _convert_GRGB_to_RGB(self, bayer16_image):
  bayer8_image = bytearray()
  # Convert bayer16 to bayer 8
  for i in range(0, len(bayer16_image), 2):
    data_byte = (bayer16_image[i] &amp; 0xF0) &gt;&gt; 4
    data_byte |= (bayer16_image[i+1] &amp; 0x0F) &lt;&lt; 4
    bayer8_image.append(data_byte)
  bayer8_image = numpy.frombuffer(bayer8_image, dtype=numpy.uint8).reshape((720, 1280))
  # Use OpenCV to convert Bayer GRGB to RGB
  return cv2.cvtColor(bayer8_image, cv2.COLOR_BayerGR2RGB)
</code></pre>

<p>After doing some timing, the for loop takes most of the running time and is extremely inefficient (although I think it does not allocate any space, unless numpy makes a copy for very edit). I am wondering how to improve this function as a whole, or the for loop in particular (as it is the slowest part of this function, by an order of magnitude).</p>

<p>Does anyone have tips and advice about how to improve this Bayer16 -> RGB conversion if I am to use Python please?</p>

<p><strong>EDIT:</strong></p>

<p>I found a solution using numpy array that makes my code pretty fast:</p>

<pre><code>def _convert_GRGB_to_RGB(self, data_bytes):
  even = numpy.frombuffer(data_bytes[0::2], dtype=numpy.uint8)
  odd = numpy.frombuffer(data_bytes[1::2], dtype=numpy.uint8)
  # Convert bayer16 to bayer8
  even = numpy.right_shift(even, 4)
  odd = numpy.left_shift(odd, 4)
  bayer8_image = numpy.bitwise_or(even, odd).reshape((720, 1280))
  # Use OpenCV to convert Bayer GRGB to RGB
  return cv2.cvtColor(bayer8_image, cv2.COLOR_BayerGR2RGB)
</code></pre>

<p>This solution satisfies my need but if anyone has any suggestion, I'm curious to hear them!</p>

<p>Your can use standard python operators in your numpyified code, You'll also get a speedup by not slicing data_bytes (assuming it's <code>bytes</code> and not itself a numpy array)</p>

<pre><code>def _convert_GRGB_to_RGB(self, data_bytes):
    data_bytes = numpy.frombuffer(data_bytes, dtype=numpy.uint8)
    even = data_bytes[0::2]
    odd = data_bytes[1::2]
    # Convert bayer16 to bayer8
    bayer8_image = (even &gt;&gt; 4) | (odd &lt;&lt; 4)
    bayer8_image = bayer8_image.reshape((720, 1280))
    # Use OpenCV to convert Bayer GRGB to RGB
    return cv2.cvtColor(bayer8_image, cv2.COLOR_BayerGR2RGB)
</code></pre>

python image numpy