init - 初始化项目
This commit is contained in:
6
samples/android/color-blob-detection/CMakeLists.txt
Normal file
6
samples/android/color-blob-detection/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
set(sample example-color-blob-detection)
|
||||
|
||||
add_android_project(${sample} "${CMAKE_CURRENT_SOURCE_DIR}" LIBRARY_DEPS "${OPENCV_ANDROID_LIB_DIR}" SDK_TARGET 11 "${ANDROID_SDK_TARGET}")
|
||||
if(TARGET ${sample})
|
||||
add_dependencies(opencv_android_examples ${sample})
|
||||
endif()
|
||||
31
samples/android/color-blob-detection/build.gradle.in
Normal file
31
samples/android/color-blob-detection/build.gradle.in
Normal file
@@ -0,0 +1,31 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
|
||||
defaultConfig {
|
||||
applicationId "org.opencv.samples.colorblobdetect"
|
||||
minSdkVersion @ANDROID_MIN_SDK_VERSION@
|
||||
targetSdkVersion @ANDROID_TARGET_SDK_VERSION@
|
||||
versionCode 301
|
||||
versionName "3.01"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
sourceSets {
|
||||
main {
|
||||
java.srcDirs = @ANDROID_SAMPLE_JAVA_PATH@
|
||||
aidl.srcDirs = @ANDROID_SAMPLE_JAVA_PATH@
|
||||
res.srcDirs = @ANDROID_SAMPLE_RES_PATH@
|
||||
manifest.srcFile '@ANDROID_SAMPLE_MANIFEST_PATH@'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation project(':opencv')
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.opencv.samples.colorblobdetect"
|
||||
>
|
||||
|
||||
<application
|
||||
android:label="@string/app_name"
|
||||
android:icon="@drawable/icon"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
|
||||
|
||||
<activity android:name="ColorBlobDetectionActivity"
|
||||
android:label="@string/app_name"
|
||||
android:screenOrientation="landscape"
|
||||
android:configChanges="keyboardHidden|orientation">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
<supports-screens android:resizeable="true"
|
||||
android:smallScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:largeScreens="true"
|
||||
android:anyDensity="true" />
|
||||
|
||||
<uses-permission android:name="android.permission.CAMERA"/>
|
||||
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false"/>
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
|
||||
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
|
||||
<uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>
|
||||
|
||||
</manifest>
|
||||
BIN
samples/android/color-blob-detection/res/drawable/icon.png
Normal file
BIN
samples/android/color-blob-detection/res/drawable/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,11 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
|
||||
<org.opencv.android.JavaCameraView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:id="@+id/color_blob_detection_activity_surface_view" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">OCV Color Blob Detection</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,205 @@
|
||||
package org.opencv.samples.colorblobdetect;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.opencv.android.BaseLoaderCallback;
|
||||
import org.opencv.android.CameraActivity;
|
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
|
||||
import org.opencv.android.LoaderCallbackInterface;
|
||||
import org.opencv.android.OpenCVLoader;
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.CvType;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfPoint;
|
||||
import org.opencv.core.Rect;
|
||||
import org.opencv.core.Scalar;
|
||||
import org.opencv.core.Size;
|
||||
import org.opencv.android.CameraBridgeViewBase;
|
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.view.SurfaceView;
|
||||
|
||||
public class ColorBlobDetectionActivity extends CameraActivity implements OnTouchListener, CvCameraViewListener2 {
|
||||
private static final String TAG = "OCVSample::Activity";
|
||||
|
||||
private boolean mIsColorSelected = false;
|
||||
private Mat mRgba;
|
||||
private Scalar mBlobColorRgba;
|
||||
private Scalar mBlobColorHsv;
|
||||
private ColorBlobDetector mDetector;
|
||||
private Mat mSpectrum;
|
||||
private Size SPECTRUM_SIZE;
|
||||
private Scalar CONTOUR_COLOR;
|
||||
|
||||
private CameraBridgeViewBase mOpenCvCameraView;
|
||||
|
||||
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
|
||||
@Override
|
||||
public void onManagerConnected(int status) {
|
||||
switch (status) {
|
||||
case LoaderCallbackInterface.SUCCESS:
|
||||
{
|
||||
Log.i(TAG, "OpenCV loaded successfully");
|
||||
mOpenCvCameraView.enableView();
|
||||
mOpenCvCameraView.setOnTouchListener(ColorBlobDetectionActivity.this);
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
super.onManagerConnected(status);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public ColorBlobDetectionActivity() {
|
||||
Log.i(TAG, "Instantiated new " + this.getClass());
|
||||
}
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
Log.i(TAG, "called onCreate");
|
||||
super.onCreate(savedInstanceState);
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
|
||||
setContentView(R.layout.color_blob_detection_surface_view);
|
||||
|
||||
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.color_blob_detection_activity_surface_view);
|
||||
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
|
||||
mOpenCvCameraView.setCvCameraViewListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause()
|
||||
{
|
||||
super.onPause();
|
||||
if (mOpenCvCameraView != null)
|
||||
mOpenCvCameraView.disableView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
if (!OpenCVLoader.initDebug()) {
|
||||
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
|
||||
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
|
||||
} else {
|
||||
Log.d(TAG, "OpenCV library found inside package. Using it!");
|
||||
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
|
||||
return Collections.singletonList(mOpenCvCameraView);
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mOpenCvCameraView != null)
|
||||
mOpenCvCameraView.disableView();
|
||||
}
|
||||
|
||||
public void onCameraViewStarted(int width, int height) {
|
||||
mRgba = new Mat(height, width, CvType.CV_8UC4);
|
||||
mDetector = new ColorBlobDetector();
|
||||
mSpectrum = new Mat();
|
||||
mBlobColorRgba = new Scalar(255);
|
||||
mBlobColorHsv = new Scalar(255);
|
||||
SPECTRUM_SIZE = new Size(200, 64);
|
||||
CONTOUR_COLOR = new Scalar(255,0,0,255);
|
||||
}
|
||||
|
||||
public void onCameraViewStopped() {
|
||||
mRgba.release();
|
||||
}
|
||||
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
int cols = mRgba.cols();
|
||||
int rows = mRgba.rows();
|
||||
|
||||
int xOffset = (mOpenCvCameraView.getWidth() - cols) / 2;
|
||||
int yOffset = (mOpenCvCameraView.getHeight() - rows) / 2;
|
||||
|
||||
int x = (int)event.getX() - xOffset;
|
||||
int y = (int)event.getY() - yOffset;
|
||||
|
||||
Log.i(TAG, "Touch image coordinates: (" + x + ", " + y + ")");
|
||||
|
||||
if ((x < 0) || (y < 0) || (x > cols) || (y > rows)) return false;
|
||||
|
||||
Rect touchedRect = new Rect();
|
||||
|
||||
touchedRect.x = (x>4) ? x-4 : 0;
|
||||
touchedRect.y = (y>4) ? y-4 : 0;
|
||||
|
||||
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 touchedRegionRgba = mRgba.submat(touchedRect);
|
||||
|
||||
Mat touchedRegionHsv = new Mat();
|
||||
Imgproc.cvtColor(touchedRegionRgba, touchedRegionHsv, Imgproc.COLOR_RGB2HSV_FULL);
|
||||
|
||||
// Calculate average color of touched region
|
||||
mBlobColorHsv = Core.sumElems(touchedRegionHsv);
|
||||
int pointCount = touchedRect.width*touchedRect.height;
|
||||
for (int i = 0; i < mBlobColorHsv.val.length; i++)
|
||||
mBlobColorHsv.val[i] /= pointCount;
|
||||
|
||||
mBlobColorRgba = convertScalarHsv2Rgba(mBlobColorHsv);
|
||||
|
||||
Log.i(TAG, "Touched rgba color: (" + mBlobColorRgba.val[0] + ", " + mBlobColorRgba.val[1] +
|
||||
", " + mBlobColorRgba.val[2] + ", " + mBlobColorRgba.val[3] + ")");
|
||||
|
||||
mDetector.setHsvColor(mBlobColorHsv);
|
||||
|
||||
Imgproc.resize(mDetector.getSpectrum(), mSpectrum, SPECTRUM_SIZE, 0, 0, Imgproc.INTER_LINEAR_EXACT);
|
||||
|
||||
mIsColorSelected = true;
|
||||
|
||||
touchedRegionRgba.release();
|
||||
touchedRegionHsv.release();
|
||||
|
||||
return false; // don't need subsequent touch events
|
||||
}
|
||||
|
||||
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
|
||||
mRgba = inputFrame.rgba();
|
||||
|
||||
if (mIsColorSelected) {
|
||||
mDetector.process(mRgba);
|
||||
List<MatOfPoint> contours = mDetector.getContours();
|
||||
Log.i(TAG, "Contours count: " + contours.size());
|
||||
Imgproc.drawContours(mRgba, contours, -1, CONTOUR_COLOR);
|
||||
|
||||
Mat colorLabel = mRgba.submat(4, 68, 4, 68);
|
||||
colorLabel.setTo(mBlobColorRgba);
|
||||
|
||||
Mat spectrumLabel = mRgba.submat(4, 4 + mSpectrum.rows(), 70, 70 + mSpectrum.cols());
|
||||
mSpectrum.copyTo(spectrumLabel);
|
||||
}
|
||||
|
||||
return mRgba;
|
||||
}
|
||||
|
||||
private Scalar convertScalarHsv2Rgba(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));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
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 {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user