找到相机预览中最亮的像素

时间:2018-03-14 15:18:40

标签: android colors camera tracker

需要帮助来修复这些代码行以找到最亮的像素及其坐标(x,y)并在其上绘制位图。 我有安卓预览实时摄像头,想通过循环并将预设的浮动brightestValue与像素[]的每个值进行比较,扫描我的过程代码在onPreviewFframe中的屏幕。我的画布静态画在屏幕左上方的圆圈。 我希望在改变相机方向的同时改变相机表面视图上的圆圈位置。对不起,如果我的英语语法不好 谢谢

public class CameraDemo extends Activity {
private static final String TAG = "CameraDemo";
Preview preview;
int brightestX = 0; // X-coordinate of the brightest video pixel
int brightestY = 0; // Y-coordinate of the brightest video pixel

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Paint p = new Paint ();
    p.setColor(Color.WHITE);
    Bitmap bg = Bitmap.createBitmap(480,800,Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bg);
    canvas.drawCircle(brightestX,brightestY,20,p);
    preview = new Preview(this);
    preview.setBackground(new BitmapDrawable(bg));
    ((FrameLayout) findViewById(R.id.preview)).addView(preview);
    }

class Preview extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback {
    SurfaceHolder mHolder;
    Camera mCamera;
    private Camera.Parameters parameters;
    private Camera.Size previewSize;
    private int[] pixels;
    Preview(Context context) {
        super(context);
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, acquire the camera and tell it where
        // to draw.
        mCamera = Camera.open();

        try {
            mCamera.startPreview();
            mCamera.setPreviewDisplay(holder);
            mCamera.setDisplayOrientation(90);
            mCamera.setPreviewCallbackWithBuffer(this);
            parameters = mCamera.getParameters();
            previewSize = parameters.getPreviewSize();

        } catch (IOException exception) {
            mCamera.release();
            mCamera = null;
            // TODO: add more exception handling logic here
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        mCamera.release();
        mCamera = null;
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        parameters.setPreviewSize(w, h);
        //set the camera's settings
        mCamera.setParameters(parameters);
        mCamera.startPreview();
    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        //transforms NV21 pixel data into RGB pixels
        decodeYUV420SP(pixels, data, previewSize.width,  previewSize.height);
        float brightestValue = 0; // Brightness of the brightest video pixel
        for (int y = 0; y < previewSize.height ; y++) {
            for (int x = 0; x < previewSize.width; x++) {
                // Get the color stored in the pixel
                float pixelBrightness = pixels[previewSize.width*previewSize.height];
                // If that value is brighter than any previous, then store the
                // brightness of that pixel, as well as its (x,y) location
                if (pixelBrightness > brightestValue) {
                    brightestValue = pixelBrightness;
                    brightestY = y;
                    brightestX = x;
                }
            }
        }
    }
}
    //Method from Ketai project! Not mine! See below...
    void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {

        final int frameSize = width * height;

        for (int j = 0, yp = 0; j < height; j++) {       int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
            for (int i = 0; i < width; i++, yp++) {
                int y = (0xff & ((int) yuv420sp[yp])) - 16;
                if (y < 0)
                    y = 0;
                if ((i & 1) == 0) {
                    v = (0xff & yuv420sp[uvp++]) - 128;
                    u = (0xff & yuv420sp[uvp++]) - 128;
                }
                int y1192 = 1192 * y;
                int r = (y1192 + 1634 * v);
                int g = (y1192 - 833 * v - 400 * u);
                int b = (y1192 + 2066 * u);

                if (r < 0)                  r = 0;               else if (r > 262143)
                    r = 262143;
                if (g < 0)                  g = 0;               else if (g > 262143)
                    g = 262143;
                if (b < 0)                  b = 0;               else if (b > 262143)
                    b = 262143;

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

1 个答案:

答案 0 :(得分:0)

您需要在更新canvas.drawCircle(brightestX,brightestY,20,p);方法中的位置后调用onPreviewFrame,因此代码如下所示:

 if (pixelBrightness > brightestValue) {
                    brightestValue = pixelBrightness;
                    brightestY = y;
                    brightestX = x;
                    drawCircleOnNewPosition() // method that calls canvas.drawCircle
                }