Error in onPictureTaken(), issue is cant converting RGB to GRAY, program stop running from cvtcolor() function.?

StackOverflow https://stackoverflow.com/questions/22377093

Question

Hey guys i m getting trouble with this function, this function is called after photo capturing and now i want to use data of image for distance transform. and count the exact number of objects i know where is problem but i cant solve it, I think problem is at Imgproc.cvtColor(m, mGray, Imgproc.COLOR_BGRA2GRAY) when i debug it program stop running at this point so please answer me if you found something; Thank you in advance

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        Log.i(TAG, "Divyesh Saving a bitmap to file");
        // The camera preview was automatically stopped. Start it again.
        mCamera.startPreview();
        Log.i(TAG, "Divyesh Start preview");
        mCamera.setPreviewCallback(this);
        Log.i(TAG, "Divyesh Start preview callback");
        // Write the image in a file (in jpeg format)
        try {
            FileOutputStream fos = new FileOutputStream(mPictureFileName);
            Log.i(TAG, "Divyesh FOS open");

            fos.write(data);
            Log.i(TAG, "Divyesh FOS write");
            Mat photo = new Mat();
            Log.i(TAG, "Divyesh Mat photo = new Mat()");
            photo.put(0, 0, data); 
            Log.i(TAG, "Divyesh photo.put");

            m = new Mat(photo.height(), photo.width(), CvType.CV_8U,new Scalar(4));
            Log.i(TAG, "Divyesh Mat value of M and height width");
            //Bitmap myBitmap32 = photo.copy(Bitmap.Config.ARGB_8888, true);
            //Utils.bitmapToMat(myBitmap32, m);


                    Imgproc.cvtColor(m, mGray, Imgproc.COLOR_BGRA2GRAY);
                    Log.i(TAG, "Divyesh CVTCOLOR");
                    Imgproc.distanceTransform(mGray, mBin, Imgproc.DIST_LABEL_PIXEL, 3);
                    Core.normalize(mBin, mBin, 0, 1., Core.NORM_MINMAX);
                    Imgproc.threshold(mBin, mBin, .5, 1., Imgproc.THRESH_BINARY);
                    mBin.convertTo(dist_8u, CvType.CV_8U);
                    hierarchy = new Mat();
                    temp = dist_8u;
                    Imgproc.findContours(dist_8u, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
                    fu = contours.size();
                    Log.i(TAG, fu + "finally got no of objects");



            fos.close();

        } catch (java.io.IOException e) {
            Log.e("PictureDemo", "Exception in photoCallback", e);
        }


    }

}

and LOGCAT

03-14 11:11:39.089: D/CameraBridge(2350): mStretch value: 1.0
03-14 11:11:39.109: D/JavaCameraView(2350): Preview Frame received. Frame size: 115200
03-14 11:11:39.149: D/CameraBridge(2350): mStretch value: 1.0
03-14 11:11:39.149: I/OCVSample::Activity(2350): onTouch event
03-14 11:11:39.159: I/Sample::Tutorial3View(2350): Taking picture
03-14 11:11:39.969: I/Sample::Tutorial3View(2350): Divyesh Saving a bitmap to file
03-14 11:11:40.209: I/Sample::Tutorial3View(2350): Divyesh Start preview
03-14 11:11:40.209: I/Sample::Tutorial3View(2350): Divyesh Start preview callback
03-14 11:11:40.219: I/Sample::Tutorial3View(2350): Divyesh FOS open
03-14 11:11:40.229: I/Sample::Tutorial3View(2350): Divyesh FOS write
03-14 11:11:40.229: I/Sample::Tutorial3View(2350): Divyesh Mat photo = new Mat()
03-14 11:11:40.229: I/Sample::Tutorial3View(2350): Divyesh photo.put
03-14 11:11:40.229: I/Sample::Tutorial3View(2350): Divyesh Mat value of M and height width
03-14 11:11:40.229: D/AndroidRuntime(2350): Shutting down VM
Was it helpful?

Solution

You don't mention the capture size, but from the Frame size Log I guess is 320x240. In Android captures are typically not in RGBA but YV12; hence size=width x height x bits_per_pixel = 320 x 240 x 1.5 = 115200. In that case, you're using the wrong conversion formats, you should use a 1-channel input Mat (because a YV12 is interpreted, wrongly, as planar by OpenCV) and then (this code is C++ but you get the idea):

cv::Mat yv12_image(height, width, CV_8UC1, input_buffer);
cv::Mat rgb_image;
cv::cvtColor(yv12_image, rgb_image, CV_YUV2RGB_YV12);

(Careful with RGB vs BGR btw). I think I recall there isn't direct conversion from YUV to Gray in cvtColor, in that case you can either walk the input buffer and convert it via any formula around, which would be slow, or run the code above (translated to Java) and then do another cvtColor from RGB to Gray.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top