diff --git a/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionActivity.java b/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionActivity.java index ecb053301d..a47eb466b8 100644 --- a/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionActivity.java +++ b/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionActivity.java @@ -9,7 +9,7 @@ import android.view.Window; public class ColorBlobDetectionActivity extends Activity { - private static final String TAG = "Example/CollorBlobDetection"; + private static final String TAG = "Example/ColorBlobDetection"; private ColorBlobDetectionView mView; public ColorBlobDetectionActivity() diff --git a/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionView.java b/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionView.java index ddca9b1b71..b5c1275105 100644 --- a/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionView.java +++ b/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionView.java @@ -1,17 +1,14 @@ package org.opencv.samples.colorblobdetect; -import java.util.ArrayList; -import java.util.Iterator; import java.util.List; - import org.opencv.android.Utils; 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.Rect; import org.opencv.core.Scalar; +import org.opencv.core.Size; import org.opencv.highgui.Highgui; import org.opencv.highgui.VideoCapture; import org.opencv.imgproc.Imgproc; @@ -29,24 +26,16 @@ public class ColorBlobDetectionView extends SampleCvViewBase implements OnTouchL private Mat mRgba; private boolean mIsColorSelected = false; - private Scalar mSelectedColorRgba = new Scalar(255); - private Scalar mSelectedColorHsv = new Scalar(255); - - // Lower and Upper bounds for range checking in HSV color space - private Scalar mLowerBound = new Scalar(0); - private Scalar mUpperBound = new Scalar(0); - + private Scalar mBlobColorRgba = new Scalar(255); + private Scalar mBlobColorHsv = new Scalar(255); + private ColorBlobDetector mDetector = new ColorBlobDetector(); private Mat mSpectrum = new Mat(); - private int mSpectrumScale = 4; - - // Color radius for range checking in HSV color space - private static final Scalar COLOR_RADIUS = new Scalar(25,50,50,0); - - // Minimum contour area in percent for contours filtering - private static final double MIN_CONTOUR_AREA = 0.1; + private static Size SPECTRUM_SIZE = new Size(200, 32); // Logcat tag - private static final String TAG = "Example/CollorBlobDetection"; + private static final String TAG = "Example/ColorBlobDetection"; + + private static final Scalar CONTOUR_COLOR = new Scalar(255,0,0,255); public ColorBlobDetectionView(Context context) @@ -85,63 +74,30 @@ public class ColorBlobDetectionView extends SampleCvViewBase implements OnTouchL touchedRect.x = (x>4) ? x-4 : 0; touchedRect.y = (y>4) ? y-4 : 0; - touchedRect.width = (x+4= COLOR_RADIUS.val[0]) ? mSelectedColorHsv.val[0]-COLOR_RADIUS.val[0] : 0; - double maxH = (mSelectedColorHsv.val[0]+COLOR_RADIUS.val[0] <= 255) ? mSelectedColorHsv.val[0]+COLOR_RADIUS.val[0] : 255; - - mLowerBound.val[0] = minH; - mUpperBound.val[0] = maxH; + Log.i(TAG, "Touched rgba color: (" + mBlobColorRgba.val[0] + ", " + mBlobColorRgba.val[1] + + ", " + mBlobColorRgba.val[2] + ", " + mBlobColorRgba.val[3] + ")"); - mLowerBound.val[1] = mSelectedColorHsv.val[1] - COLOR_RADIUS.val[1]; - mUpperBound.val[1] = mSelectedColorHsv.val[1] + COLOR_RADIUS.val[1]; + mDetector.setHsvColor(mBlobColorHsv); - mLowerBound.val[2] = mSelectedColorHsv.val[2] - COLOR_RADIUS.val[2]; - mUpperBound.val[2] = mSelectedColorHsv.val[2] + COLOR_RADIUS.val[2]; - - Log.d(TAG, "Bounds: " + mLowerBound + "x" + mUpperBound); - - Mat spectrumHsv = new Mat(32, (int)(maxH-minH)*mSpectrumScale, CvType.CV_8UC3); - - for (int i = 0; i < 32; i++) - { - for (int k = 0; k < mSpectrumScale; k++) - { - for (int j = 0; j < maxH-minH; j++) - { - byte[] tmp = {(byte)(minH+j), (byte)255, (byte)255}; - spectrumHsv.put(i, j*mSpectrumScale + k, tmp); - } - } - } - - Imgproc.cvtColor(spectrumHsv, mSpectrum, Imgproc.COLOR_HSV2RGB_FULL, 4); + Imgproc.resize(mDetector.getSpectrum(), mSpectrum, SPECTRUM_SIZE); mIsColorSelected = true; @@ -155,61 +111,17 @@ public class ColorBlobDetectionView extends SampleCvViewBase implements OnTouchL Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888); if (mIsColorSelected) - { - Mat PyrDownMat = new Mat(); - - Imgproc.pyrDown(mRgba, PyrDownMat); - Imgproc.pyrDown(PyrDownMat, PyrDownMat); - - Mat hsvMat = new Mat(); - Imgproc.cvtColor(PyrDownMat, hsvMat, Imgproc.COLOR_RGB2HSV_FULL); - - Mat rangedHsvMat = new Mat(); - Core.inRange(hsvMat, mLowerBound, mUpperBound, rangedHsvMat); - - Mat dilatedMat = new Mat(); - Imgproc.dilate(rangedHsvMat, dilatedMat, new Mat()); - - List contours = new ArrayList(); - Mat hierarchy = new Mat(); - - Imgproc.findContours(dilatedMat, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); + { + mDetector.process(mRgba); + List contours = mDetector.getContours(); + Log.e(TAG, "Contours count: " + contours.size()); + Core.drawContours(mRgba, contours, -1, CONTOUR_COLOR); - // Find max contour area - double maxArea = 0; - Iterator it = contours.iterator(); - while (it.hasNext()) - { - MatOfPoint wrapper = it.next(); - double area = Imgproc.contourArea(wrapper); - if (area > maxArea) - maxArea = area; - } + Mat colorLabel = mRgba.submat(2, 34, 2, 34); + colorLabel.setTo(mBlobColorRgba); - // Filter contours by area and resize to fit the original image size - List filteredContours = new ArrayList(); - it = contours.iterator(); - while (it.hasNext()) - { - MatOfPoint wrapper = it.next(); - if (Imgproc.contourArea(wrapper) > MIN_CONTOUR_AREA*maxArea); - Point[] contour = wrapper.toArray(); - for (int i = 0; i < contour.length; i++) - { - // Original image was pyrDown twice - contour[i].x *= 4; - contour[i].y *= 4; - } - filteredContours.add(new MatOfPoint(contour)); - } - - Core.drawContours(mRgba, filteredContours, -1, new Scalar(255,0,0,255)); - - Mat testColorMat = mRgba.submat(2, 34, 2, 34); - testColorMat.setTo(mSelectedColorRgba); - - Mat testSpectrumMat = mRgba.submat(2, 34, 38, 38 + mSpectrum.cols()); - mSpectrum.copyTo(testSpectrumMat); + Mat spectrumLabel = mRgba.submat(2, 2 + mSpectrum.rows(), 38, 38 + mSpectrum.cols()); + mSpectrum.copyTo(spectrumLabel); } try { @@ -223,6 +135,15 @@ public class ColorBlobDetectionView extends SampleCvViewBase implements OnTouchL return bmp; } + private Scalar converScalarHsv2Rgba(Scalar hsvColor) + { + Mat pointMatRgba = new Mat(); + Mat pointMatHsv = new Mat(1, 1, CvType.CV_8UC3, hsvColor); + Imgproc.cvtColor(pointMatHsv, pointMatRgba, Imgproc.COLOR_HSV2RGB_FULL, 4); + + return new Scalar(pointMatRgba.get(0, 0)); + } + @Override public void run() { super.run(); diff --git a/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetector.java b/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetector.java new file mode 100644 index 0000000000..19eeb3b204 --- /dev/null +++ b/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetector.java @@ -0,0 +1,119 @@ +package org.opencv.samples.colorblobdetect; + +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 +{ + 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) + { + Mat pyrDownMat = new Mat(); + + Imgproc.pyrDown(rgbaImage, pyrDownMat); + Imgproc.pyrDown(pyrDownMat, pyrDownMat); + + Mat hsvMat = new Mat(); + Imgproc.cvtColor(pyrDownMat, hsvMat, Imgproc.COLOR_RGB2HSV_FULL); + + Mat Mask = new Mat(); + Core.inRange(hsvMat, mLowerBound, mUpperBound, Mask); + Mat dilatedMask = new Mat(); + Imgproc.dilate(Mask, dilatedMask, new Mat()); + + List contours = new ArrayList(); + Mat hierarchy = new Mat(); + + Imgproc.findContours(dilatedMask, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); + + // Find max contour area + double maxArea = 0; + Iterator 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 getContours() + { + return mContours; + } + + // 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 mContours = new ArrayList();; +}