Java tutorial
/* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package in.fabinpaul.sixthsense; import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.core.MatOfPoint; import org.opencv.core.Point; import org.opencv.core.Scalar; import org.opencv.imgproc.Imgproc; import java.util.ArrayList; import java.util.Iterator; import java.util.List; 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(5, 30, 50, 0); private Mat mSpectrum = new Mat(); private List<MatOfPoint> mContours = new ArrayList<MatOfPoint>(); Point marker; // 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; } public Point getXY() { marker = new Point(); for (int i = 0; i < mMask.rows(); i++) { for (int j = 0; j < mMask.cols(); j++) { } } return marker; } }