I have written code to read in an image from gallery, then apply inRange()
on it to find blue colored blob and create mask, then used findContours()
to find contours, and the drawContours()
to draw the contours, then boundingRect()
to find a rectangle around the first contour, and then submat()
to extract out the submatrix. Then I used Mat.zeroes()
to create a mask from that rectangular submat. Then I applied Imgproc.calcHist()
to create a histogram, and passed in the Mask as the 3rd argument so that the histogram calculated is that of the area inside the contour only.
Following are two screen shots from my Genymotion emulator, first showing the original Mat with green contours around blue detected blobs and the submatrix I mentioned; the second shows the histogram bmp image stored in sdcard. It is plain black. The question is why is it like this, where is my histogram graph?
HISTOGRAM:
Code:
//Get the image from file path
rgbaMat = new Mat();
rgbaMatCopy = new Mat();
rgbaMat = Highgui.imread(filePath);
rgbaMatCopy = Highgui.imread(filePath);
//Preprocessing - color space conversion
Imgproc.cvtColor(rgbaMat, rgbaMat, Imgproc.COLOR_BGR2RGB);
Imgproc.cvtColor(rgbaMatCopy, rgbaMatCopy, Imgproc.COLOR_BGR2RGB);
Mat hsvMat = new Mat();
Imgproc.cvtColor(rgbaMatCopy, hsvMat, Imgproc.COLOR_RGB2HSV);
//Make the mask from the detected blue colored blob(s)
Scalar lowerThreshold = new Scalar(100, 146, 148);
Scalar upperThreshold = new Scalar(134, 255, 255);
Mat mask = new Mat();
Core.inRange(hsvMat, lowerThreshold, upperThreshold, mask);
//Preprocessing
Mat dilatedMask = new Mat();
Imgproc.dilate(mask, dilatedMask, new Mat());
Imgproc.dilate(dilatedMask, dilatedMask, new Mat());
//Find the contours
contours = new ArrayList<>();
Imgproc.findContours(dilatedMask, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
//Draw the contours
for (int contourIdx = 0; contourIdx < contours.size(); contourIdx++) {
Imgproc.drawContours(rgbaMatCopy, contours, contourIdx, new Scalar(0, 255, 0), 1);
}
//Convert the mat with contours drawn to bitmap and display in imageView
Bitmap theBitmap = Bitmap.createBitmap(rgbaMatCopy.cols(), rgbaMatCopy.rows(),
Bitmap.Config.ARGB_8888);
Utils.matToBitmap(rgbaMatCopy, theBitmap);
imageView.setImageBitmap(theBitmap);
//Find and cut out the smallest bounding rectangle around the first contour from the list of contours
MatOfPoint firstContour = contours.get(0);
Rect firstContourBoundingRect = Imgproc.boundingRect(firstContour);
Mat objectSubmat = new Mat();
objectSubmat = rgbaMat.submat(firstContourBoundingRect);
Bitmap objectSubmatBitmap = Bitmap.createBitmap(objectSubmat.cols(), objectSubmat.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(objectSubmat, objectSubmatBitmap);
imageViewOne.setImageBitmap(objectSubmatBitmap);
//Create mask of the region inside the contour
Mat regionMask = Mat.zeros(objectSubmat.rows(), objectSubmat.cols(), CvType.CV_8UC1);
List<MatOfPoint> firstList = new ArrayList<MatOfPoint>();
firstList.add(firstContour);
Imgproc.drawContours(regionMask, firstList, 0, new Scalar(255), -1);
//Preprocessing - color space conversion
Mat regionHsv = new Mat();
Imgproc.cvtColor(objectSubmat, regionHsv, Imgproc.COLOR_RGB2HSV);
//Calculate Histogram
List<Mat> sourceImageList = new ArrayList<Mat>();
sourceImageList.add(regionHsv);
Mat histogram = new Mat();
//histogramMat.convertTo(histogramMat, CvType.CV_8UC2);
Imgproc.calcHist(sourceImageList, new MatOfInt(2), regionMask, histogram, new MatOfInt(256),
new MatOfFloat(0f, 256f));
Highgui.imwrite("/mnt/sdcard/histogram.bmp", histogram);