2017-09-28 8 views
0

이 질문은 여러 번 이미 물어 보았습니다. 그러나 나는 정확하게 내가 원하는 것을 찾을 수 없습니다. 카메라를 몇 가지 색상으로 가리키면 로그에 YUV 또는 RGB 값을 표시하려는 카메라 앱을 만들려고합니다. 값은 RGB 또는 해당 YUV 색상 형식의 경우 0 ~ 255 범위 여야합니다. 스택 오버 플로우와 같은 많은 예제가 있으므로 스택 사이의 변환을 관리 할 수 ​​있습니다. 그러나, 나는 3 개의 별도 변수에 값을 저장하고 로그에 표시 할 수 없습니다.라이브 카메라 미리보기에서 YUV 값을 표시하십시오. Android

지금까지 내가 여기

package com.example.virus.bpreader; 

public class CaptureVideo extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback { 

private SurfaceHolder mHolder; 
private Camera mCamera; 
private int[] pixels; 

public CaptureVideo(Context context, Camera cameraManager) { 
    super(context); 

    mCamera = cameraManager; 
    mCamera.setDisplayOrientation(90); 

    //get holder and set the class as callback 
    mHolder = getHolder(); 
    mHolder.addCallback(this); 
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL); 
} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 

    //when the surface is created, let the camera start the preview 
    try { 
     mCamera.setPreviewDisplay(holder); 
     mCamera.startPreview(); 
     mCamera.cancelAutoFocus(); 

     Camera.Parameters params = mCamera.getParameters(); 
     //get fps 
     params.getSupportedPreviewFpsRange(); 
     //get resolution 
     params.getSupportedPreviewSizes(); 
     //stop auto exposure 
     params.setAutoExposureLock(false); 

     // Check what resolutions are supported by your camera 
     List<Camera.Size> sizes = params.getSupportedPictureSizes(); 
     // Iterate through all available resolutions and choose one 
     for (Camera.Size size : sizes) { 
      Log.i("Resolution", "Available resolution: " + size.width + " " + size.height); 
     } 
     //set resolution at 320*240 
     params.setPreviewSize(320,240); 

     //set frame rate at 10 fps 
     List<int[]> frameRates = params.getSupportedPreviewFpsRange(); 
     int last = frameRates.size() - 1; 
     params.setPreviewFpsRange(10000, 10000); 
     //set Image Format 
     //params.setPreviewFormat(ImageFormat.NV21); 
     mCamera.setParameters(params); 


    } catch (IOException e) { 
     e.printStackTrace(); 
    } 


} 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
    //need to stop the preview and restart on orientation change 
    if (mHolder.getSurface() == null) { 
     return; 
    } 
    //stop preview 
    mCamera.stopPreview(); 

    //start again 
    try { 
     mCamera.setPreviewDisplay(holder); 
     mCamera.startPreview(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 


} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
    //stop and release 
    mCamera.startPreview(); 
    mCamera.release(); 
} 

@Override 
public void onPreviewFrame(byte[] data, Camera camera) { 

    int frameHeight = camera.getParameters().getPreviewSize().height; 
    int frameWidth = camera.getParameters().getPreviewSize().width; 
    // number of pixels//transforms NV21 pixel data into RGB pixels 
    int rgb[] = new int[frameWidth * frameHeight]; 
    // convertion 
    int[] myPixels = decodeYUV420SP(rgb, data, frameWidth, frameHeight); 

    Log.d("myPixel", String.valueOf(myPixels.length)); 

} 

//yuv decode 
int[] decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) { 

    final int frameSize = width * height; 
    int r, g, b, y1192, y, i, uvp, u, v; 
    for (int j = 0, yp = 0; j < height; j++) { 
     uvp = frameSize + (j >> 1) * width; 
     u = 0; 
     v = 0; 
     for (i = 0; i < width; i++, yp++) { 
      y = (0xff & ((int) yuv420sp[yp])) - 16; 
      if (y < 0) 
       y = 0; 
      if ((i & 1) == 0) { 
       // above answer is wrong at the following lines. just swap ***u*** and ***v*** 
       u = (0xff & yuv420sp[uvp++]) - 128; 
       v = (0xff & yuv420sp[uvp++]) - 128; 
      } 

      y1192 = 1192 * y; 
      r = (y1192 + 1634 * v); 
      g = (y1192 - 833 * v - 400 * u); 
      b = (y1192 + 2066 * u); 

      r = Math.max(0, Math.min(r, 262143)); 
      g = Math.max(0, Math.min(g, 262143)); 
      b = Math.max(0, Math.min(b, 262143)); 

      // combine RGB 
      rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) | 0xff); 
     } 
    } 
return rgb; 
} 
} 

가 디코딩 방법은 RGB 색 공간의 진수 형식을 제공해야합니다 (확신의 답변의 대부분도 같은 모든 권리로) 얻을 관리했다. 내가 직면하고있는 문제는 RGB 값을 별도로 로그에 표시 할 수 있도록 OnPreviewFrame 메서드 내부에서 호출하는 방법을 잘 모르는 경우입니다.

N.B처럼 나는 비슷한 질문을 많이 보았지만 해결 방법을 찾지 못했습니다. 필자는 카메라를 어떤 색으로 가리킬 때 라이브 카메라 미리보기에서 RGB/YUV 값만 필요하기 때문에 파일 (이미지/비디오)을 저장하고 싶지 않습니다.

시간 대비 그래프를 그려보고 싶기 때문에 rgb 또는 yuv 값이 필요합니다.

도움이 될 것입니다.

+0

당신은'onPreviewFrame' 메소드 안에 어떤 값도 얻지 못합니까? 로그 안에? – MadScientist

+0

정확히 내 문제. 나는 onPreviewFrame 안에 값을 얻으려고 애쓰는 방법으로 질문을 업데이트했다. 하지만 이해, myPixels 배열을 반환합니다. 어떻게 RGB로 분리합니까? – Mill3r

+0

장치가 320x240 픽셀 해상도와 10FPS를 지원합니까? 이 경우에도 logcat은 ~ 230K 정수를 초당 10 번 인쇄 할 수 없습니다. 이 비율로 한 픽셀에 RGB를 인쇄 할 수 있습니다. –

답변

0

문제가 RGB 배열에서 R, G 및 B의 개별 값을 얻는 것이라면이 게시물 (here)을 확인하십시오.

희망 하시겠습니까?

+0

나는 이것을 따르려고했지만 디코드 또는 onPreviewFrame 내부에 로그를 남긴다면 어떤 이유로 든 logcat에서 어떤 것도 얻지 못한다. – Mill3r

+0

당신이 방법 때문에'실례가 없네요,'decodeYUV'가 void를 돌려줍니다. 따라서 픽셀 배열이 비어 있습니다. 따라서, 메소드에서 rgb [] return을 만들거나 data []를 사용하여 RGB 값을 기록하십시오. – MadScientist

+0

나는이 질문을 게시 한 후에 그것을했다. void를 int []로 변경하고 끝에 return rgb;를 추가했습니다. then add when 'int color = (int) Long.parseLong (myPixels, 16); INT의 R = (컬러 >> 16) & 0xFF; INT의 g = (컬러 >> 8) & 0xFF; B = INT (컬러 >> 0) 0xFF' 내부'onPreviewFrame', 그것은 한 String.valueOf 추가달라고. 나도 그랬어. 그러나 여전히 사용하지 않습니다. – Mill3r