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 android.app.Activity; import android.app.Fragment; import android.hardware.Camera.Size; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.MotionEvent; import android.view.SurfaceView; import android.view.View; import android.view.View.OnTouchListener; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.Toast; import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame; import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2; 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.imgproc.Imgproc; import java.util.List; import java.util.ListIterator; public class ColorBlobDetectionFragment extends Fragment implements OnTouchListener, CvCameraViewListener2 { private static final String TAG = ColorBlobDetectionFragment.class.getSimpleName(); private boolean[] mIsColorSelected = { false, false, false, false }; private Mat mRgba; private Scalar[] mBlobColorRgba = new Scalar[4]; private Scalar[] mBlobColorHsv = new Scalar[4]; private ColorBlobDetector[] mDetector = new ColorBlobDetector[4]; private int count = -1; private Scalar CONTOUR_COLOR; private boolean colorMarkerSet = false; private Communicator comm; private CameraView mOpenCvCameraView; private List<Size> mResolutionList; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); Log.i(TAG, "onActivityCreated"); mOpenCvCameraView = (CameraView) getActivity() .findViewById(R.id.color_blob_detection_activity_surface_view); mOpenCvCameraView.setCvCameraViewListener(this); comm = (Communicator) getActivity(); setHasOptionsMenu(true); } @Override public void onAttach(Activity activity) { super.onAttach(activity); } @Override public void onCreate(Bundle savedInstanceState) { Log.i(TAG, "called onCreate"); super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.color_blob_detection_surface_view, container, true); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { mResolutionList = getResolutionList(); if (mResolutionList == null) return; MenuItem[] resolutionMenuItems = new MenuItem[mResolutionList.size()]; Log.i(TAG, "Menu created"); ListIterator<Size> resolutionItr = mResolutionList.listIterator(); int idx = 0; while (resolutionItr.hasNext()) { android.hardware.Camera.Size element = resolutionItr.next(); resolutionMenuItems[idx] = menu.add(2, idx, Menu.NONE, Integer.valueOf(element.width).toString() + "x" + Integer.valueOf(element.height).toString()); idx++; } } @Override public boolean onOptionsItemSelected(MenuItem item) { Log.i(TAG, "called onOptionsItemSelected; selected item: " + item); int id = item.getItemId(); android.hardware.Camera.Size resolution = mResolutionList.get(id); setResolution(resolution); resolution = getResolution(); String caption = Integer.valueOf(resolution.width).toString() + "x" + Integer.valueOf(resolution.height).toString(); Toast.makeText(getActivity(), caption, Toast.LENGTH_SHORT).show(); return true; } @Override public void onDetach() { super.onDetach(); } @Override public void onCameraViewStarted(int width, int height) { mRgba = new Mat(height, width, CvType.CV_8UC4); for (int i = 0; i < 4; i++) { mDetector[i] = new ColorBlobDetector(); mBlobColorRgba[i] = new Scalar(255); mBlobColorHsv[i] = new Scalar(255); } CONTOUR_COLOR = new Scalar(255, 0, 0, 255); getActivity().invalidateOptionsMenu(); } public Mat onCameraFrame(CvCameraViewFrame inputFrame) { mRgba = inputFrame.rgba(); Mat[] colorLabel = new Mat[4]; org.opencv.core.Point markersXY[] = new org.opencv.core.Point[4]; for (int i = 0; i < 4; i++) { colorLabel[i] = new Mat(); if (mIsColorSelected[i]) { mDetector[i].process(mRgba); List<MatOfPoint> contours = mDetector[i].getContours(); Log.e(TAG, "Contours count: " + contours.size()); Imgproc.drawContours(mRgba, contours, -1, CONTOUR_COLOR); markersXY[i] = new org.opencv.core.Point(); markersXY[i] = mDetector[i].getXY(); Log.i(TAG, "Point:X" + markersXY[i].x + " Y:" + markersXY[i].y); switch (i) { case 0: colorLabel[i] = mRgba.submat(4, 68, 4, 68); break; case 1: colorLabel[i] = mRgba.submat(4, 68, mRgba.cols() - 68, mRgba.cols() - 4); break; case 2: colorLabel[i] = mRgba.submat(mRgba.rows() - 68, mRgba.rows() - 4, 4, 68); break; case 3: colorLabel[i] = mRgba.submat(mRgba.rows() - 68, mRgba.rows() - 4, mRgba.cols() - 68, mRgba.cols() - 4); break; } colorLabel[i].setTo(mBlobColorRgba[i]); } } return mRgba; } @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { count++; if (count > 3) count = 0; if (count == 3) { colorMarkerSet = true; comm.saveButtonVisibility(); } int cols = mRgba.cols(); int rows = mRgba.rows(); int xOffset = (mOpenCvCameraView.getWidth() - cols) / 2; int yOffset = (mOpenCvCameraView.getHeight() - rows) / 2; Log.i(TAG, "x coordinates" + event.getX() + "y coordinates" + event.getY()); Log.i(TAG, "View width" + mOpenCvCameraView.getWidth() + "View Height" + mOpenCvCameraView.getHeight()); int x = (int) event.getX() - xOffset; int y = (int) event.getY() - yOffset; 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 - 1 - touchedRect.x : cols - touchedRect.x; touchedRect.height = (y + 4 < rows) ? y - 1 - touchedRect.y : rows - touchedRect.y; Log.i(TAG, "Width" + touchedRect.width + " Height" + touchedRect.height); Log.i(TAG, "Column" + cols + " Rows" + rows); Log.i(TAG, "Touch image coordinates: (" + x + ", " + 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[count] = Core.sumElems(touchedRegionHsv); int pointCount = touchedRect.width * touchedRect.height; for (int i = 0; i < mBlobColorHsv[count].val.length; i++) mBlobColorHsv[count].val[i] /= pointCount; mBlobColorRgba[count] = converScalarHsv2Rgba(mBlobColorHsv[count]); Log.i(TAG, "Before" + mBlobColorHsv[count].val[0] + " " + mBlobColorHsv[count].val[1] + " " + mBlobColorHsv[count].val[2]); Log.i(TAG, "After" + mBlobColorRgba[count].val[0] + " " + mBlobColorRgba[count].val[1] + " " + mBlobColorRgba[count].val[2]); Log.i(TAG, "Touched rgba color: (" + mBlobColorRgba[count].val[0] + ", " + mBlobColorRgba[count].val[1] + ", " + mBlobColorRgba[count].val[2] + ", " + mBlobColorRgba[count].val[3] + ")"); // mDetector[count].setHsvColor(mBlobColorHsv[count]); setHSV(count); mIsColorSelected[count] = true; touchedRegionRgba.release(); touchedRegionHsv.release(); } return true; // don't need subsequent touch events } public float getHSV(String channel, int id) { if (channel.equalsIgnoreCase("hue")) return (float) mBlobColorHsv[id].val[0]; else if (channel.equalsIgnoreCase("saturation")) return (float) mBlobColorHsv[id].val[1]; else if (channel.equalsIgnoreCase("value")) return (float) mBlobColorHsv[id].val[2]; else return (float) mBlobColorHsv[id].val[3]; } public void setHSV(String channel, int id, float value) { if (channel.equalsIgnoreCase("hue")) { mBlobColorHsv[id].val[0] = value; Log.i(TAG, "Hue" + id + "," + value); } else if (channel.equalsIgnoreCase("saturation")) { mBlobColorHsv[id].val[1] = value; Log.i(TAG, "Saturataion" + value); } else if (channel.equalsIgnoreCase("value")) { mBlobColorHsv[id].val[2] = value; Log.i(TAG, "Value" + value); } else if (channel.equalsIgnoreCase("temp")) { mBlobColorHsv[id].val[3] = value; Log.i(TAG, "Temp" + value); } } public void setHSV(int id) { mDetector[id].setHsvColor(mBlobColorHsv[id]); } public void clearMarkers() { for (int i = 0; i < 4; i++) { mIsColorSelected[i] = false; } } public float getRGBA(String color, int id) { if (color.equalsIgnoreCase("red")) return (float) mBlobColorRgba[id].val[0]; else if (color.equalsIgnoreCase("green")) return (float) mBlobColorRgba[id].val[1]; else if (color.equalsIgnoreCase("blue")) return (float) mBlobColorRgba[id].val[2]; else if (color.equalsIgnoreCase("alpha")) return (float) mBlobColorRgba[id].val[3]; else return 0; } public void setRGBA(String color, int id, float value) { if (color.equalsIgnoreCase("red")) mBlobColorRgba[id].val[0] = value; else if (color.equalsIgnoreCase("green")) mBlobColorRgba[id].val[1] = value; else if (color.equalsIgnoreCase("blue")) mBlobColorRgba[id].val[2] = value; else if (color.equalsIgnoreCase("alpha")) mBlobColorRgba[id].val[3] = value; } public void setColorSelected(int id) { mIsColorSelected[id] = true; } 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 onCameraViewStopped() { mRgba.release(); } public void initialize() { Log.i(TAG, "OpenCV loaded successfully"); Log.i(TAG, "" + mOpenCvCameraView); mOpenCvCameraView.enableView(); mOpenCvCameraView.setOnTouchListener(ColorBlobDetectionFragment.this); } public void toggleVisibilityOn() { mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE); } public void toggleVisibilityGone() { mOpenCvCameraView.setVisibility(SurfaceView.GONE); } public void disableView() { if (mOpenCvCameraView != null) mOpenCvCameraView.disableView(); } public List<Size> getResolutionList() { return mOpenCvCameraView.getResolutionList(); } public void setResolution(Size resolution) { mOpenCvCameraView.setResolution(resolution); } public Size getResolution() { return mOpenCvCameraView.getResolution(); } public LayoutParams getLayoutParams() { return mOpenCvCameraView.getLayoutParams(); } public boolean isColorMarkerSet() { return colorMarkerSet; } }