Python Color Palettize Camera Frame非常慢

时间:2017-06-22 11:46:56

标签: python performance numpy raspberry-pi vectorization

在Raspberry Pi上的Linux中,我使用Python来控制PiCamera和FLIR Lepton IR传感器。我通过在每个帧的嵌入式for循环中替换值来对IR图像进行颜色调色。这是非常缓慢的预期。我可以使用任何numpy或opencv技巧来加速Python吗?

慢代码:

      for i in xrange(lepton_buf.shape[0]):    
        for j in xrange(lepton_buf.shape[1]):    
          current_value = 3 * lepton_buf[i,j]    
          new_lepton_buf[i,j,:] = np.array([colormap_rainbow[current_value],colormap_rainbow[current_value+1],colormap_rainbow[current_value+2]], dtype=np.uint8)    
      a[:lepton_buf.shape[0], :lepton_buf.shape[1], :] = new_lepton_buf

完整代码

  # Create an array representing a 1280x720 image of   
  # a cross through the center of the display. The shape of   
  # the array must be of the form (height, width, color)    
  a = np.zeros((240, 320, 3), dtype=np.uint8)    
  lepton_buf = np.zeros((60, 80, 1), dtype=np.uint16)    
  new_lepton_buf = np.zeros((60, 80, 3), dtype=np.uint8)    

  with picamera.PiCamera() as camera:    
    camera.resolution = (640, 480)    
    camera.framerate = 24    
    camera.vflip = flip_v    
    camera.start_preview()    
    camera.zoom = (0.0, 0.0, 1.0, 1.0)    
    # Add the overlay directly into layer 3 with transparency;    
    # we can omit the size parameter of add_overlay as the    
    # size is the same as the camera's resolution

    o = camera.add_overlay(np.getbuffer(a), size=(320,240), layer=3, alpha=int(alpha), crop=(0,0,80,60), vflip=flip_v)    
    try:    
      time.sleep(0.2) # give the overlay buffers a chance to initialize    
      with Lepton(device) as l:    
        last_nr = 0    
        while True:    
          _,nr = l.capture(lepton_buf)    
          if nr == last_nr:    
            # no need to redo this frame    
            continue    
          last_nr = nr    
          cv2.normalize(lepton_buf, lepton_buf, 0, 65535, cv2.NORM_MINMAX) # extend contrast    
          np.right_shift(lepton_buf, 8, lepton_buf) # fit data into 8 bits    
          for i in xrange(lepton_buf.shape[0]):    
            for j in xrange(lepton_buf.shape[1]):    
              current_value = 3 * lepton_buf[i,j]    
              new_lepton_buf[i,j,:] = np.array([colormap_rainbow[current_value],colormap_rainbow[current_value+1],colormap_rainbow[current_value+2]], dtype=np.uint8)    
          a[:lepton_buf.shape[0], :lepton_buf.shape[1], :] = new_lepton_buf    
          o.update(np.getbuffer(a))

    except Exception:    
      traceback.print_exc()    
    finally:    
      camera.remove_overlay(o)

colormap rainbow看起来像这样:

colormap_rainbow = [1, 3, 74, 0, 3, 74, 0, 3, 75, 0, 3, 75, 0, 3, 76, 0, 3, 76, 0, 3, 77, 0, 3, 79, 0, 3, 82, 0, 5, 85, 0, 7, 88, 0, 10, 91, 0, 14, 94, 0, 19, 98, 0, 22, 100, 0, 25, 103, 0, 28, 106, 0, 32, 109, 0, 35, 112, 0, 38, 116, 0, 40, 119, 0, 42, 123, 0, 45, 128, 0, 49, 133, 0, 50, 134, 0, 51, 136, 0, 52, 137, 0, 53, 139, 0, 54, 142, 0, 55, 144, 0, 56, 145, 0, 58, 149, 0, 61, 154, 0, 63, 156, 0, 65, 159, 0, 66, 161, 0, 68, 164, 0, 69, 167, 0, 71, 170, 0, 73, 174, 0, 75, 179, 0, 76, 181, 0, 78, 184, 0, 79, 187, 0, 80, 188, 0, 81, 190, 0, 84, 194, 0, 87, 198, 0, 88, 200, 0, 90, 203, 0, 92, 205, 0, 94, 207, 0, 94, 208, 0, 95, 209, 0, 96, 210, 0, 97, 211, 0, 99, 214, 0, 102, 217, 0, 103, 218, 0, 104, 219, 0, 105, 220, 0, 107, 221, 0, 109, 223, 0, 111, 223, 0, 113, 223, 0, 115, 222, 0, 117, 221, 0, 118, 220, 1, 120, 219, 1, 122, 217, 2, 124, 216, 2, 126, 214, 3, 129, 212, 3, 131, 207, 4, 132, 205, 4, 133, 202, 4, 134, 197, 5, 136, 192, 6, 138, 185, 7, 141, 178, 8, 142, 172, 10, 144, 166, 10, 144, 162, 11, 145, 158, 12, 146, 153, 13, 147, 149, 15, 149, 140, 17, 151, 132, 22, 153, 120, 25, 154, 115, 28, 156, 109, 34, 158, 101, 40, 160, 94, 45, 162, 86, 51, 164, 79, 59, 167, 69, 67, 171, 60, 72, 173, 54, 78, 175, 48, 83, 177, 43, 89, 179, 39, 93, 181, 35, 98, 183, 31, 105, 185, 26, 109, 187, 23, 113, 188, 21, 118, 189, 19, 123, 191, 17, 128, 193, 14, 134, 195, 12, 138, 196, 10, 142, 197, 8, 146, 198, 6, 151, 200, 5, 155, 201, 4, 160, 203, 3, 164, 204, 2, 169, 205, 2, 173, 206, 1, 175, 207, 1, 178, 207, 1, 184, 208, 0, 190, 210, 0, 193, 211, 0, 196, 212, 0, 199, 212, 0, 202, 213, 1, 207, 214, 2, 212, 215, 3, 215, 214, 3, 218, 214, 3, 220, 213, 3, 222, 213, 4, 224, 212, 4, 225, 212, 5, 226, 212, 5, 229, 211, 5, 232, 211, 6, 232, 211, 6, 233, 211, 6, 234, 210, 6, 235, 210, 7, 236, 209, 7, 237, 208, 8, 239, 206, 8, 241, 204, 9, 242, 203, 9, 244, 202, 10, 244, 201, 10, 245, 200, 10, 245, 199, 11, 246, 198, 11, 247, 197, 12, 248, 194, 13, 249, 191, 14, 250, 189, 14, 251, 187, 15, 251, 185, 16, 252, 183, 17, 252, 178, 18, 253, 174, 19, 253, 171, 19, 254, 168, 20, 254, 165, 21, 254, 164, 21, 255, 163, 22, 255, 161, 22, 255, 159, 23, 255, 157, 23, 255, 155, 24, 255, 149, 25, 255, 143, 27, 255, 139, 28, 255, 135, 30, 255, 131, 31, 255, 127, 32, 255, 118, 34, 255, 110, 36, 255, 104, 37, 255, 101, 38, 255, 99, 39, 255, 93, 40, 255, 88, 42, 254, 82, 43, 254, 77, 45, 254, 69, 47, 254, 62, 49, 253, 57, 50, 253, 53, 52, 252, 49, 53, 252, 45, 55, 251, 39, 57, 251, 33, 59, 251, 32, 60, 251, 31, 60, 251, 30, 61, 251, 29, 61, 251, 28, 62, 250, 27, 63, 250, 27, 65, 249, 26, 66, 249, 26, 68, 248, 25, 70, 248, 24, 73, 247, 24, 75, 247, 25, 77, 247, 25, 79, 247, 26, 81, 247, 32, 83, 247, 35, 85, 247, 38, 86, 247, 42, 88, 247, 46, 90, 247, 50, 92, 248, 55, 94, 248, 59, 96, 248, 64, 98, 248, 72, 101, 249, 81, 104, 249, 87, 106, 250, 93, 108, 250, 95, 109, 250, 98, 110, 250, 100, 111, 251, 101, 112, 251, 102, 113, 251, 109, 117, 252, 116, 121, 252, 121, 123, 253, 126, 126, 253, 130, 128, 254, 135, 131, 254, 139, 133, 254, 144, 136, 254, 151, 140, 255, 158, 144, 255, 163, 146, 255, 168, 149, 255, 173, 152, 255, 176, 153, 255, 178, 155, 255, 184, 160, 255, 191, 165, 255, 195, 168, 255, 199, 172, 255, 203, 175, 255, 207, 179, 255, 211, 182, 255, 216, 185, 255, 218, 190, 255, 220, 196, 255, 222, 200, 255, 225, 202, 255, 227, 204, 255, 230, 206, 255, 233, 208]

1 个答案:

答案 0 :(得分:1)

在将lepton_buf扩展到3D之后,您可以使用NumPy broadcasting一次性生成所有索引,添加一个范围数组的3个数字来模拟这三个数字在每次迭代时被分配,从而提取并分配以矢量化方式获取new_lepton_buf的所有元素,如此 -

idx = 3 * lepton_buf[...,0,None] + range(3)
new_lepton_buf = colormap_rainbow[idx]

如果colormap_rainbow是列表,我们需要将其转换为数组然后索引。所以,我们可以使用:

new_lepton_buf = np.asarray(colormap_rainbow)[idx]

new_lepton_buf = np.take(colormap_rainbow, idx)