Created
June 25, 2018 19:09
-
-
Save Elvis10ten/a948cd51db03cd8accead15d92cbb142 to your computer and use it in GitHub Desktop.
OpenCv Sample: ColorBlob Detector
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.mobymagic.opencvproject; | |
| import java.util.ArrayList; | |
| import java.util.Iterator; | |
| import java.util.List; | |
| import org.opencv.core.Core; | |
| import org.opencv.core.CvType; | |
| import org.opencv.core.Mat; | |
| import org.opencv.core.MatOfPoint; | |
| import org.opencv.core.Scalar; | |
| import org.opencv.imgproc.Imgproc; | |
| public class ColorBlobDetector { | |
| // Lower and Upper bounds for range checking in HSV color space | |
| private Scalar mLowerBound = new Scalar(0); | |
| private Scalar mUpperBound = new Scalar(0); | |
| // Minimum contour area in percent for contours filtering | |
| private static double mMinContourArea = 0.1; | |
| // Color radius for range checking in HSV color space | |
| private Scalar mColorRadius = new Scalar(25,50,50,0); | |
| private Mat mSpectrum = new Mat(); | |
| private List<MatOfPoint> mContours = new ArrayList<MatOfPoint>(); | |
| // Cache | |
| Mat mPyrDownMat = new Mat(); | |
| Mat mHsvMat = new Mat(); | |
| Mat mMask = new Mat(); | |
| Mat mDilatedMask = new Mat(); | |
| Mat mHierarchy = new Mat(); | |
| public void setColorRadius(Scalar radius) { | |
| mColorRadius = radius; | |
| } | |
| public void setHsvColor(Scalar hsvColor) { | |
| double minH = (hsvColor.val[0] >= mColorRadius.val[0]) ? hsvColor.val[0]-mColorRadius.val[0] : 0; | |
| double maxH = (hsvColor.val[0]+mColorRadius.val[0] <= 255) ? hsvColor.val[0]+mColorRadius.val[0] : 255; | |
| mLowerBound.val[0] = minH; | |
| mUpperBound.val[0] = maxH; | |
| mLowerBound.val[1] = hsvColor.val[1] - mColorRadius.val[1]; | |
| mUpperBound.val[1] = hsvColor.val[1] + mColorRadius.val[1]; | |
| mLowerBound.val[2] = hsvColor.val[2] - mColorRadius.val[2]; | |
| mUpperBound.val[2] = hsvColor.val[2] + mColorRadius.val[2]; | |
| mLowerBound.val[3] = 0; | |
| mUpperBound.val[3] = 255; | |
| Mat spectrumHsv = new Mat(1, (int)(maxH-minH), CvType.CV_8UC3); | |
| for (int j = 0; j < maxH-minH; j++) { | |
| byte[] tmp = {(byte)(minH+j), (byte)255, (byte)255}; | |
| spectrumHsv.put(0, j, tmp); | |
| } | |
| Imgproc.cvtColor(spectrumHsv, mSpectrum, Imgproc.COLOR_HSV2RGB_FULL, 4); | |
| } | |
| public Mat getSpectrum() { | |
| return mSpectrum; | |
| } | |
| public void setMinContourArea(double area) { | |
| mMinContourArea = area; | |
| } | |
| public void process(Mat rgbaImage) { | |
| Imgproc.pyrDown(rgbaImage, mPyrDownMat); | |
| Imgproc.pyrDown(mPyrDownMat, mPyrDownMat); | |
| Imgproc.cvtColor(mPyrDownMat, mHsvMat, Imgproc.COLOR_RGB2HSV_FULL); | |
| Core.inRange(mHsvMat, mLowerBound, mUpperBound, mMask); | |
| Imgproc.dilate(mMask, mDilatedMask, new Mat()); | |
| List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); | |
| Imgproc.findContours(mDilatedMask, contours, mHierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); | |
| // Find max contour area | |
| double maxArea = 0; | |
| Iterator<MatOfPoint> each = contours.iterator(); | |
| while (each.hasNext()) { | |
| MatOfPoint wrapper = each.next(); | |
| double area = Imgproc.contourArea(wrapper); | |
| if (area > maxArea) | |
| maxArea = area; | |
| } | |
| // Filter contours by area and resize to fit the original image size | |
| mContours.clear(); | |
| each = contours.iterator(); | |
| while (each.hasNext()) { | |
| MatOfPoint contour = each.next(); | |
| if (Imgproc.contourArea(contour) > mMinContourArea*maxArea) { | |
| Core.multiply(contour, new Scalar(4,4), contour); | |
| mContours.add(contour); | |
| } | |
| } | |
| } | |
| public List<MatOfPoint> getContours() { | |
| return mContours; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment