Watershed example in [android] opencv - android

Currently trying
<code>
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba();
Imgproc.Canny(mRgba, markers, 80, 90);
Mat threeChannel = new Mat();
Imgproc.cvtColor(mRgba, threeChannel, Imgproc.COLOR_BGR2GRAY);
Imgproc.watershed(threeChannel, markers);
return threeChannel;
}
</code>
However, it fails with
CvException [org.opencv.core.CvException: /home/reports/ci/slave/50-SDK/opencv/modules/imgproc/src/segmentation.cpp:147: error: (-210) Only 8-bit, 3-channel input images are supported in function void cvWatershed(const CvArr*, CvArr*)
Could you advise how to appropriately use the markers from a Canny/Sobel edge detection to feed a Watershed algorithm? Android-specifics would be greatly helpful as this is my first Android project.

The error states that the input image for watershed() must be an 8-bit 3-channels image. After calling cvtColor(), print the number of channels of threeChannel. Don't be surprised if it outputs 1.
Pass mRgba directly to watershed() and see what happens. One of my previous answers have working code using watershed, you can use that for testing.

You need to just convert your image from 4 channel to 3 channels.
For example
Imgproc.cvtColor(mat , mat, Imgproc.COLOR_BGRA2BGR);

Related

Digital numbers recognition with Opencv + OCR on android

i'm currently developing an android application to recognize digital numbers of an electricity meter. i've done most of the work but i still not getting a good result. 80% of the time i get a false one.
This is an example (i'm testing with a kitchen scale which is very similar to the meter) :
Original photo :
image after cropping and processing with OpenCV :
image after OCR (expected result that was obtained after several shots) :
image after OCR (unexpected result which is obtained often) :
Method used to process the image with OpenCV :
public Bitmap Bildverarbeitung (Bitmap image){
Mat tmp = new Mat (image.getWidth(), image.getHeight(), CvType.CV_8UC1);
Utils.bitmapToMat(image, tmp);
Imgproc.cvtColor(tmp, tmp, Imgproc.COLOR_RGB2GRAY);
Imgproc.GaussianBlur(tmp, tmp, new Size(3, 3), 0);
Imgproc.threshold(tmp, tmp, 0, 255, Imgproc.THRESH_OTSU);
Utils.matToBitmap(tmp, image);
return image;
}
I used two trained data but only one works better :
traineddata that works good
traineddata that doesn't work
can anyone help me get better results.. Is there any changes that i can do? or other methods that i can apply ? thanks in advance

Capture video frames with opencv in android

I am trying to process android video in real time with opencv-android. So far I am able to access the video with opencv, and display it on a org.opencv.android.JavaCameraView.(I referred to this link) I haven't been able to access the video feed of the camera by frame-wise. I need to get each and every frame in order to apply some opencv algorithms on them for object tracking. Please suggest a method to access and process the frames with opencv. (Redirect this if it's already been asked)
Here is how to do it:
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
//Do your processing here, for example:
Mat image = inputFrame.rgba();
Mat ret_mat=new Mat();
Core.add(image, new Scalar(40, 40, 40, 0), ret_mat); //change brightness of video frame
return ret_mat;
}
OpenCv functions operate with Mat object, which represents matrix of pixels of your image/frame. The code above makes each frame brighter by 40 units.

Why does this Mat returned by rgba() method appear to have BGR format rather than RGBA format?

I have read at several places (source, source) that OpenCV uses BGR color format by default.
But I am writing a class to detect a blob of a certain color (red) in an image (following the Color Blob Detection sample). So in the onCameraFrame(CvCameraViewFrame inputFrame) function, we return the value inputFrame.rgba(). According to the documentation,
rgba() This method returns RGBA Mat with frame
So I assumed that my rgbaFrame, which is the variable storing the value of inputFrame.rgba() in my program, contains the Mat in RGBA format.
But when I run the app, the red color in the original image appeared to be bluish in the rgbaFrame Mat I wrote to the external SD card. So apparently, the Mat is in BGR format, because red is appearing to be blue. (This is discussed in the comments of this question.)
So I changed my cvtColorfunction from
Imgproc.cvtColor(rgbaFrame, hsvImage, Imgproc.COLOR_RGB2HSV_FULL);
to
Imgproc.cvtColor(rgbaFrame, hsvImage, Imgproc.COLOR_BGR2HSV_FULL);
But nothing changed when I run the program. Red in original image still appears blue in the captured frame.
So now I am looking for a way to convert RGB to BGR format, to try and see if that helps solve my problem. But have failed to find one.
How do I convert BGR to RGB? Please share if you have any other suggestions for me.
original screenshot from which camera frame is captured:
rgbaFrame.jpg (because I did Highgui.imwrite("/mnt/sdcard/DCIM/rgbaFrame.jpg", rgbaFrame);//check)
OpenCV uses BGR by default, however, Android frame.rgba() implementation returns RGB (possibly for compliance with imageview and other Android components). However, the OpenCV function imwrite still requires BGR, therefore if you save the image without first converting it to BGR then the blue and red channels are saved incorrectly (swapped), because the Mat file of the frame has red channel in index 0 (RGB) whereas imwrite writes index 0 as blue (BGR). Similarly the frame has blue channel in index 2 whereas imwrite writes index 2 as red. You can call cvtcolor with COLOR_RGB2BGR before saving to a file.
/**
* Callback method that is called on every frame of the CameraBridgeViewBase class of OpenCV
*/
override fun onCameraFrame(inputFrame: CameraBridgeViewBase.CvCameraViewFrame?): Mat {
inputFrame?.let { currentFrame ->
val currentFrameMat = currentFrame.rgba()
// save the RGB2BGR converted version
val convertedMat = Mat()
Imgproc.cvtColor(currentFrameMat, convertedMat, Imgproc.COLOR_RGB2BGR)
Imgcodecs.imwrite(imageFilePath, convertedMat)
return currentFrameMat
}
return Mat()
}

OpenCVAndroid Imgproc.GaussianBlur application stopped

I'm newbie OCV and android developer. I want Imgproc.GaussianBlur filter in my app. When i use it application send "application stopped". I only add 3 lines to "OpenCV Tutorial 3 - Camera Control":
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
Mat mat = inputFrame.gray();
org.opencv.core.Size s = mat.size();
Imgproc.GaussianBlur(mat, mat, s, 2);
return mat;
}
What could be wrong? I have Lenovo A820 Android 4.1.2 and tried it on OpenCV 2.4.4, 2.4.5 and 2.4.6. I tried different API. The Imgproc.Sobel(mat,mat,-1,1,1); filter works good.
look at the docs for GaussianBlur
it says: "ksize – Gaussian kernel size. ksize.width and ksize.height can differ but they both must be positive and odd."
so, imho, you confused the kernel size with the Mat's size, try something like:
Mat mat = inputFrame.gray();
org.opencv.core.Size s = new Size(3,3);
Imgproc.GaussianBlur(mat, mat, s, 2);
return mat;

Mat::convertto() not working in javacv, android camera

I am developing an Android OpenCV app based on Opencv4android SDK tutorial 2 - Mixed Processing.
in the frame processing function public Mat onCameraFrame(CvCameraViewFrame inputFrame) {}
The frame is RGBA and I want to make RGB by doing this:
mRgba = inputFrame.rgba();
mGray = inputFrame.gray();
Mat mRgb=new Mat(640,480,CvType.CV_8UC3);
mRgba.convertTo(mRgb, CvType.CV_8UC3);
//Imgproc.cvtColor(mRgba, mRgb, CvType.CV_8UC3);
PinkImage(mRgb.dataAddr());
But when I debug and log the things I passed to the JNI part, I find it's not working at all.
mRgb is CV_8UC4 even after calling converto()
What is the cause of this?
OK, the answer is here
Imgproc.cvtColor(mRgba,mRgb,Imgproc.COLOR_RGBA2RGB);
instead of
mRgba.convertTo(mRgb, CvType.CV_8UC3);
Thanks a lot!!
You never use the converted data. You still pass mRgba.dataAddr() to PinkImage(), which is the unmodified RGBA image. You need to pass in the modified data:
PinkImage(mRgb.dataAddr());

Categories

Resources