ColorBlobDetection example. Pyrdown added. Contour area filtering added.
This commit is contained in:
parent
ba238562c6
commit
b7c1fd34b9
@ -1,9 +1,20 @@
|
||||
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.highgui.Highgui;
|
||||
import org.opencv.highgui.VideoCapture;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
@ -13,11 +24,19 @@ import android.view.SurfaceHolder;
|
||||
import android.view.View;
|
||||
import android.view.View.OnTouchListener;
|
||||
|
||||
public class ColorBlobDetectionView extends SampleCvViewBase implements
|
||||
OnTouchListener {
|
||||
public class ColorBlobDetectionView extends SampleCvViewBase implements OnTouchListener {
|
||||
|
||||
private Mat mRgba;
|
||||
private static final String TAG = "Example/CollorBlobDetection";
|
||||
|
||||
private boolean mIsColorSelected = false;
|
||||
private Scalar mSelectedColorRgba = new Scalar(255);
|
||||
private Scalar mSelectedColorHsv = new Scalar(255);
|
||||
private Scalar mLowerBound = new Scalar(0);
|
||||
private Scalar mUpperBound = new Scalar(0);
|
||||
private final Scalar mColorRadius = new Scalar(25,50,50,0);
|
||||
private Mat mSpectrum = new Mat();
|
||||
private int mSpectrumScale = 4;
|
||||
|
||||
public ColorBlobDetectionView(Context context)
|
||||
{
|
||||
@ -34,23 +53,114 @@ public class ColorBlobDetectionView extends SampleCvViewBase implements
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
int cols = mRgba.cols();
|
||||
int rows = mRgba.rows();
|
||||
|
||||
Log.d(TAG, "Resolition: " + cols + "x" + rows);
|
||||
|
||||
int xoffset = (getWidth() - cols) / 2;
|
||||
int yoffset = (getHeight() - rows) / 2;
|
||||
|
||||
Log.d(TAG, "Touch offset " + xoffset + "x" + yoffset);
|
||||
|
||||
Log.d(TAG, "Screen touch coordinates: " + event.getX() + "x" + event.getY());
|
||||
|
||||
int x = (int)event.getX() - xoffset;
|
||||
int y = (int)event.getY() - yoffset;
|
||||
|
||||
double TouchedColor[] = mRgba.get(x,y);
|
||||
|
||||
Log.i(TAG, "Touch coordinates: (" + x + ", " + y + ")");
|
||||
Log.i(TAG, "Touched rgba color: (" + TouchedColor[0] + ", " + TouchedColor[1] +
|
||||
", " + TouchedColor[2] + ", " + TouchedColor[0] + ",)");
|
||||
|
||||
if ((x > cols) || (y > rows)) return false;
|
||||
|
||||
Rect TouchedRect = new Rect();
|
||||
|
||||
if (x-4 >= 0)
|
||||
TouchedRect.x = x-4;
|
||||
else
|
||||
TouchedRect.x = 0;
|
||||
|
||||
if (y-4 >= 0)
|
||||
TouchedRect.y = y-4;
|
||||
else
|
||||
TouchedRect.y = 0;
|
||||
|
||||
if (x+4 < mRgba.cols())
|
||||
TouchedRect.width = x + 4 - TouchedRect.x;
|
||||
else
|
||||
TouchedRect.width = mRgba.width() - TouchedRect.x;
|
||||
|
||||
if (y+4 < mRgba.rows())
|
||||
TouchedRect.height = y+4 - TouchedRect.y;
|
||||
else
|
||||
TouchedRect.height = mRgba.rows() - TouchedRect.y;
|
||||
|
||||
Mat TouchedRegionMat = mRgba.submat(TouchedRect);
|
||||
Mat TouchedRegionMatHsv = new Mat();
|
||||
|
||||
Imgproc.cvtColor(TouchedRegionMat, TouchedRegionMatHsv, Imgproc.COLOR_RGB2HSV_FULL);
|
||||
|
||||
mSelectedColorHsv = Core.sumElems(TouchedRegionMatHsv);
|
||||
int DotCount = TouchedRect.width*TouchedRect.height;
|
||||
for (int i = 0; i < mSelectedColorHsv.val.length; i++)
|
||||
{
|
||||
mSelectedColorHsv.val[i] /= DotCount;
|
||||
}
|
||||
|
||||
Mat rgbaDotMap = new Mat();
|
||||
Mat hsvDotMat = new Mat(1, 1, CvType.CV_8UC3);
|
||||
|
||||
byte[] buf = {(byte)mSelectedColorHsv.val[0], (byte)mSelectedColorHsv.val[1], (byte)mSelectedColorHsv.val[2]};
|
||||
|
||||
hsvDotMat.put(0, 0, buf);
|
||||
Imgproc.cvtColor(hsvDotMat, rgbaDotMap, Imgproc.COLOR_HSV2RGB_FULL, 4);
|
||||
|
||||
mSelectedColorRgba.val = rgbaDotMap.get(0, 0);
|
||||
|
||||
Log.i(TAG, "Touched rgba color: (" + mSelectedColorRgba.val[0] + ", " + mSelectedColorRgba.val[1] +
|
||||
", " + mSelectedColorRgba.val[2] + ", " + mSelectedColorRgba.val[3] + ")");
|
||||
|
||||
double MinH = 0;
|
||||
double MaxH = 255;
|
||||
|
||||
if (mSelectedColorHsv.val[0]-mColorRadius.val[0] >= 0)
|
||||
MinH = mSelectedColorHsv.val[0]-mColorRadius.val[0];
|
||||
else
|
||||
MinH = 0;
|
||||
|
||||
if (mSelectedColorHsv.val[0]+mColorRadius.val[0] <= 255)
|
||||
MaxH = mSelectedColorHsv.val[0]+mColorRadius.val[0];
|
||||
else
|
||||
MaxH = 255;
|
||||
|
||||
mLowerBound.val[0] = MinH;
|
||||
mUpperBound.val[0] = MaxH;
|
||||
|
||||
mLowerBound.val[1] = mSelectedColorHsv.val[1] - mColorRadius.val[1];
|
||||
mUpperBound.val[1] = mSelectedColorHsv.val[1] + mColorRadius.val[1];
|
||||
|
||||
mLowerBound.val[2] = mSelectedColorHsv.val[2] - mColorRadius.val[2];
|
||||
mUpperBound.val[2] = mSelectedColorHsv.val[2] + mColorRadius.val[2];
|
||||
|
||||
Mat HsvSpectrum = new Mat(32, 2*(int)mColorRadius.val[0]*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};
|
||||
HsvSpectrum.put(i, j*mSpectrumScale + k, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Imgproc.cvtColor(HsvSpectrum, mSpectrum, Imgproc.COLOR_HSV2RGB_FULL, 4);
|
||||
|
||||
mIsColorSelected = true;
|
||||
|
||||
return false; // don't need subsequent touch events
|
||||
}
|
||||
@ -61,6 +171,66 @@ public class ColorBlobDetectionView extends SampleCvViewBase implements
|
||||
capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
|
||||
|
||||
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);
|
||||
|
||||
Log.d(TAG, "Bounds: " + mLowerBound + "x" + mUpperBound);
|
||||
|
||||
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);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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) > 0.01*MaxArea);
|
||||
Point[] contour = wrapper.toArray();
|
||||
for (int i = 0; i < contour.length; i++)
|
||||
{
|
||||
contour[i].x *= 4;
|
||||
contour[i].y *= 4;
|
||||
}
|
||||
FilteredContours.add(new MatOfPoint(contour));
|
||||
}
|
||||
|
||||
Imgproc.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);
|
||||
}
|
||||
|
||||
try {
|
||||
Utils.matToBitmap(mRgba, bmp);
|
||||
} catch(Exception e) {
|
||||
|
Loading…
Reference in New Issue
Block a user