2017-04-24 59 views
1

我從相機中獲得了YUV_420_888圖像。我想從該圖像的灰度中裁剪出一個矩形以供給圖像處理算法。這是我到目前爲止有:從相機2中裁剪出一個矩形圖像

public static byte[] YUV_420_888toCroppedY(Image image, Rect cropRect) { 
    byte[] yData; 

    ByteBuffer yBuffer = image.getPlanes()[0].getBuffer(); 

    int ySize = yBuffer.remaining(); 

    yData = new byte[ySize]; 

    yBuffer.get(yData, 0, ySize); 

    if (cropRect != null) { 

     int cropArea = (cropRect.right - cropRect.left) * (cropRect.bottom - cropRect.top); 

     byte[] croppedY = new byte[cropArea]; 

     int cropIndex = 0; 

     // from the top of the rectangle, to the bottom, sequentially add rows to the output array, croppedY 
     for (int y = cropRect.top; y < cropRect.top + cropRect.height(); y++) { 

      // (2x+W) * y + x 
      int rowStart = (2*cropRect.left + cropRect.width()) * y + cropRect.left; 

      // (2x+W) * y + x + W 
      int rowEnd = (2*cropRect.left + cropRect.width()) * y + cropRect.left + cropRect.width(); 

      for (int x = rowStart; x < rowEnd; x++) { 
       croppedY[cropIndex] = yData[x]; 
       cropIndex++; 
      } 
     } 

     return croppedY; 
    } 

    return yData; 
} 

此功能沒有錯誤運行,但我把它弄出來的圖像是垃圾 - 它看起來是這樣的:

enter image description here

我不是確定如何解決這個問題或我做錯了什麼。

+2

我想你應該張貼原始圖像 –

+0

@YandryPozo我沒有它,我通過我的預覽屏幕看了看,它看起來並不像 – Carpetfizz

+1

你可能通過讀取gralloc和android緩衝區找到答案:https://source.android.com/devices/graphics/arch-bq-gralloc。這是一個很好的概述,這也解釋了爲什麼緩衝區的字節寬度可能與圖像的像素寬度有所不同:https://www.codeproject.com/articles/991640/androids-graphics-buffer-management-system -Part-I – l85m

回答

1

您的rowStart/end計算錯誤。

您需要根據源圖像尺寸計算行起始位置,而不是基於裁切窗口尺寸。我不確定你從哪裏得到2的因子;在圖像的Y通道中每個像素有1個字節。

他們應該大致爲:

int yRowStride = image.getPlanes()[0].getRowStride(); 
.. 
int rowStart = y * yRowStride + cropRect.left(); 
int rowEnd = y * yRowStride + cropRect.left() + cropRect.width();