CodeReview #1511 notes upplied.
authorAlexander Smorkalov <no@email>
Thu, 31 May 2012 10:54:37 +0000 (10:54 +0000)
committerAlexander Smorkalov <no@email>
Thu, 31 May 2012 10:54:37 +0000 (10:54 +0000)
samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionActivity.java
samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionView.java
samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetector.java [new file with mode: 0644]

index ecb0533..a47eb46 100644 (file)
@@ -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()
index ddca9b1..b5c1275 100644 (file)
@@ -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<mRgba.cols()) ? x + 4 - touchedRect.x : mRgba.width() - touchedRect.x;
-        touchedRect.height = (y+4 < mRgba.rows()) ? y + 4 - touchedRect.y : mRgba.rows() - touchedRect.y;
+        touchedRect.width = (x+4 < cols) ? x + 4 - touchedRect.x : cols - touchedRect.x;
+        touchedRect.height = (y+4 < rows) ? y + 4 - touchedRect.y : rows - touchedRect.y;
                
-        Mat touchedRegionMatRgba = mRgba.submat(touchedRect);
-        Mat touchedRegionMatHsv = new Mat();
+        Mat touchedRegionRgba = mRgba.submat(touchedRect);
         
-        Imgproc.cvtColor(touchedRegionMatRgba, touchedRegionMatHsv, Imgproc.COLOR_RGB2HSV_FULL);
+        Mat touchedRegionHsv = new Mat();
+        Imgproc.cvtColor(touchedRegionRgba, touchedRegionHsv, Imgproc.COLOR_RGB2HSV_FULL);
         
-        mSelectedColorHsv = Core.sumElems(touchedRegionMatHsv);
+        // Calculate average color of touched region
+        mBlobColorHsv = Core.sumElems(touchedRegionHsv);
         int pointCount = touchedRect.width*touchedRect.height;
-        for (int i = 0; i < mSelectedColorHsv.val.length; i++)
+        for (int i = 0; i < mBlobColorHsv.val.length; i++)
         {
-               mSelectedColorHsv.val[i] /= pointCount;
+               mBlobColorHsv.val[i] /= pointCount;
         }
         
-        Mat pointMapRgba = new Mat();
-        Mat pointMatHsv = new Mat(1, 1, CvType.CV_8UC3);
-        
-        byte[] buf = {(byte)mSelectedColorHsv.val[0], (byte)mSelectedColorHsv.val[1], (byte)mSelectedColorHsv.val[2]};
+        mBlobColorRgba = converScalarHsv2Rgba(mBlobColorHsv);
         
-        pointMatHsv.put(0, 0, buf);
-        Imgproc.cvtColor(pointMatHsv, pointMapRgba, Imgproc.COLOR_HSV2RGB_FULL, 4);
-        
-        mSelectedColorRgba.val = pointMapRgba.get(0, 0);
-        
-        Log.i(TAG, "Touched rgba color: (" + mSelectedColorRgba.val[0] + ", " + mSelectedColorRgba.val[1] + 
-                       ", " + mSelectedColorRgba.val[2] + ", " + mSelectedColorRgba.val[3] + ")");
-        
-       double minH = (mSelectedColorHsv.val[0] >= 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<MatOfPoint> contours = new ArrayList<MatOfPoint>();
-            Mat hierarchy = new Mat();
-
-            Imgproc.findContours(dilatedMat, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
+        {            
+               mDetector.process(mRgba);
+               List<MatOfPoint> 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<MatOfPoint> 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<MatOfPoint> filteredContours = new ArrayList<MatOfPoint>();
-            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 (file)
index 0000000..19eeb3b
--- /dev/null
@@ -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<MatOfPoint> contours = new ArrayList<MatOfPoint>();
+        Mat hierarchy = new Mat();
+
+        Imgproc.findContours(dilatedMask, contours, hierarchy, 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;
+       }
+
+       // 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>();;
+}