I am trying to extract the title bar from the image below using opencv.
I am using the following code -
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat original = Imgcodecs.imread("D:/test_bg_extract.png", Imgcodecs.CV_LOAD_IMAGE_UNCHANGED);
Mat hsvMat = new Mat();
Imgproc.cvtColor(original, hsvMat, Imgproc.COLOR_BGR2HSV);
Mat dst = new Mat();
Core.inRange(hsvMat, new Scalar(23,231,205), new Scalar(23,231,205), dst);
I used a color picker to determine the HSV value of the title bar (from the hsvMat converted to display image). When the run the code to display the output, I see a blank screen. I can't tell what I am doing wrong. Am I picking the wrong HSV color? If I know the exact RGB code then should I even be converting image to HSV? (this however seems to be the standard method from many code examples on the internet).
Ok, I solved it using RGB based color, switching to BGR while specifying the color that I need. So this worked -
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat original = Imgcodecs.imread("D:/test_bg_extract.png", Imgcodecs.CV_LOAD_IMAGE_UNCHANGED);
Mat dst = new Mat();
Core.inRange(original, new Scalar(132,178,205), new Scalar(132,178,205), dst);
Related
I'm trying to develop an application with android studio to capture the color of flashing LEDs.
Im now at this Point, that i got the positions of the LEDs and now i want to determine the bounding box center with the class moments of openCV.
Mat src = new.Mat(Bitmap.getHeight(), Bitmap.getWidth(), CvType.CV_8UC1);
Mat hsv = new Mat();
Utils.bitmapToMat(Bitmap, src);
Imgproc.cvtColor(src,hsv, Imgproc.COLOR_BGR2HSV);
Core.inRange(hsv,LOWER_RED,HIGHER_RED,hsv);
Imgproc.dilate(hsv,hsv,Imgproc.getStructuringElement(Imgproc.MORPH_VECT,new Size(50,50)));
List<MatOfPoint> contours = new ArrayList <>();
Mat hierarchy = new Mat();
Imgproc.findContours(hsv, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
hierarchy.release();
//finding Bounding Box Center
List<Moments> mu = new ArrayList<>(contours.size());
mu.add(1, Imgproc.moments(contours.get(1), false));
Utils.matToBitmap(hsv,Bitmap);
//...
And the lines with Moments brings me following error message:
No implementation found for double[] org.opencv.imgproc.Imgproc.moments_0(long, boolean) ( tried Java_org_opencv_imgproc_Imgproc_moments_10 and Java_org_opencv_imgproc_Imgproc_moments_10__JZ )
So if i jump to Imgproc.java then the method is red marked and following message popups by mouseover:
Cannot resolve corresponding JNI function Java_org_opencv_imgproc_Imgproc_moments_10
Reports native method declaration in Java where no corresponding JNI functions is found in the project.
Thanks for reading
Can anyone help me ?
My Question how to count Objects in image on Android Watershed OpenCv?
Since you didn't tell us which line causes those problem, but i strongly assume you misused erode() and dilate().
You should pass 3rd parameter of each function with valid non-zero Matrix.(e.g. Kernel)
erode & dilate example
// You can change the size of kennel
// if you want to change the range of erosion & dilation
Mat kelnel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(2,2));
Mat fg = new Mat(img.size(),CvType.CV_8U);
Imgproc.erode(threeChannel, fg, kelnel);
Mat bg = new Mat(img.size(),CvType.CV_8U);
Imgproc.dilate(threeChannel, bg, kelnel);
In my android app I get an image from the gallery as a bitmap with something like this
Bitmap bitm = getMyImage("Thanks!");
and I have a Mat called mat declared like this:
Mat mat = new Mat(bitm.getHeight(), bitm.getWidth(), CVType.CV_8UC3);
I'm trying to get contour areas from the image, which I've successfully gotten then draw it back on the original image with:
Imgproc.drawContours(mat, contours, -1, new Scalar(200,200,0), 2);
displayMat(mat);
If I use it like that, it works but the contours are drawn on a blank image which isn't what I want. I want it to be drawn on the original image. If I use
Utils.bitmapToMat(bitm, mat);
before the previous snippet of code, the displayed image is just the preprossed image without the 'Drawn' contours. Why?
Asfaik Android uses images with alpha values, so CV_8UC4 is the right data type.
So
Mat mat = new Mat(bitm.getHeight(), bitm.getWidth(), CVType.CV_8UC3);
Imgproc.drawContours(mat, contours, -1, new Scalar(200,200,0), 2);
displayMat(mat);
draws the contours correctly on an empty/blank 8UC3 image (if memory empty).
But if you want to draw on the input image by first converting Utils.bitmapToMat(bitm, mat); you'll overwrite your 8UC3 memory and replace it by 8UC4 data. After that you draw Scalar(200,200,0) which will use a 4th channel, but cv::Scalar automatically adds those channels with default zero values, so you draw your contours in transparent. So use Scalar(200,200,0,255) instead and it should give your expected results.
Mat mat = new Mat(bitm.getHeight(), bitm.getWidth(), CVType.CV_8UC3);
Utils.bitmapToMat(bitm, mat);
Imgproc.drawContours(mat, contours, -1, new Scalar(200,200,0,255), 2);
displayMat(mat);
The other method would be to convert the bitmap to 8UC3, but I'm not sure how to do that.
I'm trying to detect feature in face with goodFeatureToTrack function in java. It always crashes there. This is my code:
Mat eyeRegion = detectCascade();//i used here cascadeclassifier to detect eye region
if(eyeRegion.empty())
Log.i("face_calibrated","eye region is empty");
I make sure that my region is not empty.
if(eyeRegion.channels()==1)
{
//i convert my mat to rgb to detectfeatures
Imgproc.cvtColor(eyeRegion, eyeRegion, Imgproc.COLOR_GRAY2RGB);
Log.i("face_calibrated","eyeRegion is channel1");
}
Here is the problem:
Imgproc.goodFeaturesToTrack(eyeRegion,cornersA,4,0.01,5.0,null,3,false,0.04);
I have declared cornersA as global MatOfPoint
public MatOfPoint cornersA = new MatOfPoint();
What type of input mat (RGB or GRAY) should be used in this function?
I am developing an Android app that calculates the sum of all points of the being-seen dominoes pieces -shown in picture- using OpenCV for Android.
The problem is, I can't find a way to filtering other contours and counting only dots I see in the dominoes, I tried to use Canny edge finding then use HoughCircles, but with no result, as I don't have an absolute top view of the rocks and HoughCircles detect perfect circles only :)
Here is my code:
public Mat onCameraFrame(Mat inputFrame) {
inputFrame.copyTo(mRgba);
Mat grey = new Mat();
// Make it greyscale
Imgproc.cvtColor(mRgba, grey, Imgproc.COLOR_RGBA2GRAY);
// init contours arraylist
List<MatOfPoint> contours = new ArrayList<MatOfPoint>(200);
//blur
Imgproc.GaussianBlur(grey, grey, new Size(9,9), 10);
Imgproc.threshold(grey, grey, 80, 150, Imgproc.THRESH_BINARY);
// because findContours modifies the image I back it up
Mat greyCopy = new Mat();
grey.copyTo(greyCopy);
Imgproc.findContours(greyCopy, contours, new Mat(), Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_NONE);
// Now I have my controus pefectly
MatOfPoint2f mMOP2f1 = new MatOfPoint2f();
//a list for only selected contours
List<MatOfPoint> SelectedContours = new ArrayList<MatOfPoint>(400);
for(int i=0;i<contours.size();i++)
{
if(here I should put a condition that distinguishes my spots, eg: if contour inside is black and is a black disk)
{
SelectedContours.add(contours.get(i));
}
}
Imgproc.drawContours(mRgba, SelectedContours, -1, new Scalar(255,0,0,255), 1);
return mRgba;
}
EDIT:
One unique feature of my contours after threshold is they're totally black from inside, is there anyway I could calculate the mean color/intensity for a given contour ?
There is a similiar problem and possible solution on SO, titled Detection of coins (and fit ellipses) on an image. Here you will find some recomendations about opencv's function fitEllipse.
You should take a look at this for more info on opencv's function fitEllipse.
Also, to detect only black elements in an image, you can use HSV color model, to find only black colors. You can find an explanation here.