Back to project page compCellScope.
The source code is released under:
MIT License
If you think the Android project compCellScope listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.wallerlab.compcellscope; /* www. j a v a2s.c o m*/ import java.io.File; import java.util.ArrayList; import java.util.List; import org.opencv.android.BaseLoaderCallback; 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.Point; import org.opencv.core.Range; import org.opencv.core.Rect; import org.opencv.core.Scalar; import org.opencv.core.Size; import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2; import org.opencv.imgproc.Imgproc; import com.wallerlab.compcellscope.AcquireSettings.NoticeDialogListener; import com.wallerlab.compcellscope.MultiModeView; import android.app.Activity; import android.app.DialogFragment; import android.content.Intent; import android.hardware.Camera; import android.hardware.Camera.PictureCallback; import android.hardware.Camera.ShutterCallback; import android.media.MediaScannerConnection; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.SurfaceView; import android.view.View; import android.view.WindowManager; import android.view.View.OnTouchListener; import android.widget.Button; import android.widget.FrameLayout; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; public class MultiModeViewActivity extends Activity implements OnTouchListener, NoticeDialogListener, CvCameraViewListener2 { private static final String TAG = "cCS_MultimodeView"; private static final boolean D = true; private Camera mCamera; private AcquireSurfaceView mPreview; private BluetoothService mBluetoothService = null; private String acquireType = "MultiMode"; Button btnSetup, btnAcquire; private TextView acquireTextView; private TextView acquireTextView2; private TextView timeLeftTextView; private ProgressBar acquireProgressBar; public double objectiveNA = 0.3; public double brightfieldNA = 0.25; // Account for LED size to be sure we completly cover NA .025 public int ledCount = 508; public int centerLED = 249; PictureCallback rawCallback; ShutterCallback shutterCallback; PictureCallback jpegCallback; public String fileName = "default"; public boolean cameraReady = true; public int mmCount = 5; public float mmDelay = 0.0f; public String datasetName = "Dataset"; private int frameNum = 1; private boolean dpcSwitch = false; private static final int VIEW_MODE_RGBA = 0; private static final int VIEW_MODE_GRAY = 1; private static final int VIEW_MODE_CANNY = 2; private static final int VIEW_MODE_FEATURES = 5; private Mat mRgba; private Mat mIntermediateMat; private Mat dpcLeft; private Mat dpcRight; private Mat dpcTop; private Mat dpcBottom; private Mat mmGrid; private Mat dpcLRImg; private Mat dpcTBImg; private Mat bfImg; private Mat dfImg; private MenuItem mItemPreviewRGBA; private MenuItem mItemPreviewGray; private MenuItem mItemPreviewCanny; private MenuItem mItemPreviewFeatures; public int horzCrop = 0; public int vertCrop = 300; private Rect TLRect; private Rect TRRect; private Rect BLRect; private Rect BRRect; private int viewMode = 0; private MultiModeView 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(MultiModeViewActivity.this); } break; default: { super.onManagerConnected(status); } break; } } }; public MultiModeViewActivity() { 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); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); setContentView(R.layout.multimode_liveview_layout); mOpenCvCameraView = (MultiModeView) findViewById(R.id.mmCameraView); mOpenCvCameraView.setCvCameraViewListener(this); mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE); mOpenCvCameraView.setCvCameraViewListener(this); BluetoothApplicationClass BTAppClass = (BluetoothApplicationClass) getApplication(); mBluetoothService = BTAppClass.getBluetoothService(); } @Override public boolean onCreateOptionsMenu(Menu menu) { Log.i(TAG, "called onCreateOptionsMenu"); mItemPreviewRGBA = menu.add("Preview RGBA"); mItemPreviewGray = menu.add("Preview GRAY"); mItemPreviewCanny = menu.add("Canny"); mItemPreviewFeatures = menu.add("Find features"); return true; } @Override public void onPause() { super.onPause(); if (mOpenCvCameraView != null) mOpenCvCameraView.disableView(); } @Override public void onResume() { super.onResume(); OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback); } 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); mIntermediateMat = new Mat(height, width, CvType.CV_16UC4); dpcLeft = new Mat(height, width, CvType.CV_8UC4); dpcRight = new Mat(height, width, CvType.CV_8UC4); dpcTop = new Mat(height, width, CvType.CV_8UC4); dpcBottom = new Mat(height, width, CvType.CV_8UC4); mmGrid = new Mat(height,width,CvType.CV_8UC4); bfImg = new Mat(height,width,CvType.CV_8UC4); dfImg = new Mat(height,width,CvType.CV_8UC4); dpcLRImg = new Mat(height, width, CvType.CV_8UC4); dpcTBImg = new Mat(height, width, CvType.CV_8UC4); TLRect = new Rect(0,0,width/2,height/2); TRRect = new Rect(width/2,0,width/2,height/2); BLRect = new Rect(0,height/2,width/2,height/2); BRRect = new Rect(width/2,height/2,width/2,height/2); //mOpenCvCameraView.setMaxFrameSize(200, 200); mCamera = mOpenCvCameraView.getCameraObject(); //Set Exposure sendData("c,4"); Camera.Parameters camParams; camParams = mCamera.getParameters(); camParams.setAutoExposureLock(false); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } //camParams.setAutoExposureLock(true); mCamera.setParameters(camParams); } public void onCameraViewStopped() { mRgba.release(); mIntermediateMat.release(); } public Mat onCameraFrame(CvCameraViewFrame inputFrame) { mCamera = mOpenCvCameraView.getCameraObject(); mRgba = inputFrame.rgba(); Camera.Parameters camParams; camParams = mCamera.getParameters(); int bfCompensation = 0; int dfCompensation = 0*camParams.getMaxExposureCompensation(); if (viewMode == 0) { switch (frameNum) { case 1: // Left { mRgba.copyTo(dpcLeft); sendData("c,1"); frameNum = 2; break; } case 2: // Right { mRgba.copyTo(dpcRight); sendData("c,2"); frameNum = 3; break; } case 3: // Top { mRgba.copyTo(dpcTop); sendData("c,3"); frameNum = 4; break; } case 4: // Bottom { mRgba.copyTo(dpcBottom); sendData("c,4"); frameNum = 5; break; } case 5: // Brightfield { camParams.setExposureCompensation(bfCompensation); mCamera.setParameters(camParams); mRgba.copyTo(bfImg); sendData("c,5"); frameNum = 6; break; } case 6: // Darkfield { camParams.setExposureCompensation(dfCompensation); mCamera.setParameters(camParams); mRgba.copyTo(dfImg); sendData("c,0"); // Sleep because of exposure differences try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } frameNum = 1; break; } } } else { switch(viewMode) { case 1: { dpcSwitch = !dpcSwitch; if (dpcSwitch) { sendData("c,1"); mRgba.copyTo(dpcLeft); }else{ sendData("c,0"); mRgba.copyTo(dpcRight); } break; } case 3: { dpcSwitch = !dpcSwitch; if (dpcSwitch) { sendData("c,3"); mRgba.copyTo(dpcTop); }else{ sendData("c,2"); mRgba.copyTo(dpcBottom); } break; } case 4: { sendData("c,4"); mRgba.copyTo(bfImg); Log.d(TAG,"Printed bf img"); break; } case 5: { sendData("c,5"); mRgba.copyTo(dfImg); Log.d(TAG,"Printed df img"); break; } } } // This works, but the image appears dimmer for some reason? /* Core.add(dpcLeft, dpcRight, mIntermediateMat); Core.divide(mIntermediateMat,new Scalar(2.0,2.0,2.0,0.5),mIntermediateMat); mIntermediateMat.convertTo(bfImg, CvType.CV_8UC4); */ dpcLRImg = calcDPC(dpcLeft, dpcRight); dpcTBImg = calcDPC(dpcTop, dpcBottom); /* try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } */ if (viewMode == 0) mmGrid = generateMMFrame(bfImg,dfImg,dpcLRImg,dpcTBImg); else if (viewMode == 1) mmGrid = dpcLRImg; else if (viewMode == 3) mmGrid = dpcTBImg; else if (viewMode == 4) mmGrid = bfImg; else if (viewMode == 5) mmGrid = dfImg; return mmGrid; } public Mat calcDPC(Mat in1, Mat in2) { Mat Mat1 = new Mat(in1.width(),in1.height(), in1.type()); Mat Mat2 = new Mat(in2.width(),in2.height(), in2.type()); in1.copyTo(Mat1); in2.copyTo(Mat2); Imgproc.cvtColor(Mat1, Mat1, Imgproc.COLOR_RGBA2GRAY, 1); Imgproc.cvtColor(Mat2, Mat2, Imgproc.COLOR_RGBA2GRAY, 1); Mat output = new Mat(Mat1.width(),Mat1.height(), CvType.CV_8UC4); Mat dpcSum = new Mat(Mat1.width(), Mat1.height(), CvType.CV_32FC1); Mat dpcDifference = new Mat(Mat1.width(), Mat1.height(), CvType.CV_32FC1); Mat dpcImgF = new Mat(Mat1.width(), Mat1.height(), CvType.CV_32FC1); Log.d(TAG,String.format("Mat1 format is %.1f-%.1f, type: %d",Mat1.size().width,Mat1.size().height,Mat1.type())); Log.d(TAG,String.format("Mat2 format is %.1f-%.1f, type: %d",Mat2.size().width,Mat2.size().height,Mat2.type())); // Convert to Floats Mat1.convertTo(Mat1, CvType.CV_32FC1); Mat2.convertTo(Mat2, CvType.CV_32FC1); Core.add(Mat1, Mat2, dpcSum); Core.subtract(Mat1, Mat2, dpcDifference); Core.divide(dpcDifference, dpcSum, dpcImgF); Core.add(dpcImgF, new Scalar(1.0), dpcImgF); // Normalize to 0-2.0 Core.multiply(dpcImgF, new Scalar(110), dpcImgF); // Normalize to 0-255 dpcImgF.convertTo(output, CvType.CV_8UC1); // Convert back into RGB Imgproc.cvtColor(output, output, Imgproc.COLOR_GRAY2RGBA, 4); Imgproc.cvtColor(Mat1, Mat1, Imgproc.COLOR_GRAY2RGBA, 4); Imgproc.cvtColor(Mat2, Mat2, Imgproc.COLOR_GRAY2RGBA, 4); dpcSum.release(); dpcDifference.release(); dpcImgF.release(); Mat1.release(); Mat2.release(); Mat output2 = new Mat(output.size(),output.type()); Mat maskedImg = Mat.zeros(output.rows(), output.cols(), CvType.CV_8UC4); int radius = maskedImg.width()/2+25; Core.circle(maskedImg, new Point (maskedImg.width()/2,maskedImg.height()/2),radius, new Scalar (255,255,255),-1, 8, 0); output.copyTo(output2,maskedImg); output.release(); return output2; } public Mat generateMMFrame(Mat MatTL, Mat MatTR, Mat MatBL, Mat MatBR) { Size sz = new Size(480,800); Mat gridOut = new Mat(sz,CvType.CV_8UC4); Mat Mat1 = new Mat(MatTL.size(),MatTL.type()); Mat Mat2 = new Mat(MatTR.size(),MatTR.type()); Mat Mat3 = new Mat(MatBL.size(),MatBL.type()); Mat Mat4 = new Mat(MatBR.size(),MatBR.type()); // Ensure all of the mats are of the correct size since pyramid operation resizes Imgproc.resize( MatTL, MatTL, sz ); Imgproc.resize( MatTR, MatTR, sz ); Imgproc.resize( MatBL, MatBL, sz ); Imgproc.resize( MatBR, MatBR, sz ); // Downsample by 2 for 2x2 grid Imgproc.pyrDown(MatBL, Mat1); Imgproc.pyrDown(MatBR, Mat2); Imgproc.pyrDown(MatTL, Mat3); Imgproc.pyrDown(MatTR, Mat4); /* Log.d(TAG,String.format("TLRect format is %.1f-%.1f",TLRect.size().width,TLRect.size().height)); Log.d(TAG,String.format("TRRect format is %.1f-%.1f",TRRect.size().width,TRRect.size().height)); Log.d(TAG,String.format("BLRect format is %.1f-%.1f",BLRect.size().width,BLRect.size().height)); Log.d(TAG,String.format("BRRect format is %.1f-%.1f",BRRect.size().width,BRRect.size().height)); Log.d(TAG,String.format("MatTL format is %.1f-%.1f",MatTL.size().width,MatTL.size().height)); Log.d(TAG,String.format("MatTR format is %.1f-%.1f",MatTR.size().width,MatTR.size().height)); Log.d(TAG,String.format("MatBL format is %.1f-%.1f",MatBL.size().width,MatBL.size().height)); Log.d(TAG,String.format("MatBR format is %.1f-%.1f",MatBR.size().width,MatBR.size().height)); */ Core.putText(Mat1, "DPC-LR", new Point(43,40), Core.FONT_ITALIC, 1, new Scalar(255,255,0)); Core.putText(Mat2, "DPC-TB", new Point(43,40), Core.FONT_ITALIC, 1, new Scalar(255,255,0)); Core.putText(Mat3, "BrightField", new Point(33,40), Core.FONT_ITALIC, 1, new Scalar(255,255,0)); Core.putText(Mat4, "DarkField", new Point(37,40), Core.FONT_ITALIC, 1, new Scalar(255,255,0)); Mat1.copyTo(gridOut.submat(BLRect)); Mat2.copyTo(gridOut.submat(BRRect)); Mat3.copyTo(gridOut.submat(TLRect)); Mat4.copyTo(gridOut.submat(TRRect)); Mat1.release(); Mat2.release(); Mat3.release(); Mat4.release(); return gridOut; } public boolean onOptionsItemSelected(MenuItem item) { Log.i(TAG, "called onOptionsItemSelected; selected item: " + item); /* if (item == mItemPreviewRGBA) { mViewMode = VIEW_MODE_RGBA; } else if (item == mItemPreviewGray) { mViewMode = VIEW_MODE_GRAY; } else if (item == mItemPreviewCanny) { mViewMode = VIEW_MODE_CANNY; } else if (item == mItemPreviewFeatures) { mViewMode = VIEW_MODE_FEATURES; } */ return true; } @Override public void onDialogPositiveClick(DialogFragment dialog) { // TODO Auto-generated method stub } @Override public void onDialogNegativeClick(DialogFragment dialog) { // TODO Auto-generated method stub } @Override public boolean onTouch(View v, MotionEvent event) { if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { if (viewMode == 0) { // Determine set new view based on where the user touched if ((int)event.getY() < v.getHeight()/2 ) { if ((int)event.getX() > v.getWidth()/2) viewMode = 5; else viewMode = 4; }else{ if ((int)event.getX() > v.getWidth()/2) viewMode = 3; else viewMode = 1; } } else viewMode = 0; // Set back to multimode display } return false; } public void sendData(String message) { // Check that we're actually connected before trying anything if (mBluetoothService.getState() != BluetoothService.STATE_CONNECTED) { Toast.makeText(this, "NOT CONNECTED", Toast.LENGTH_SHORT).show(); return; } // Check that there's actually something to send if (message.length() > 0) { // Get the message bytes and tell the BluetoothChatService to write byte[] send = message.getBytes(); mBluetoothService.write(send); } } //fire intent to start activity with proper configuration for acquire type protected void startGalleryActivity() { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setDataAndType(Uri.parse("file://" + Environment.getExternalStorageDirectory() + "/CellScope/20140815_163448496/"), "image/*"); startActivity(intent); } public void updateFileStructure(String currPath) { File f = new File(currPath); File[] fileList = f.listFiles(); ArrayList<String> arrayFiles = new ArrayList<String>(); if (!(fileList.length == 0)) { for (int i=0; i<fileList.length; i++) arrayFiles.add(currPath+"/"+fileList[i].getName()); } String[] fileListString = new String[arrayFiles.size()]; fileListString = arrayFiles.toArray(fileListString); MediaScannerConnection.scanFile(MultiModeViewActivity.this, fileListString, null, new MediaScannerConnection.OnScanCompletedListener() { public void onScanCompleted(String path, Uri uri) { //Log.i("TAG", "Finished scanning " + path); } }); } public void openSettingsDialog() { //settingsDialogFragment.show(getFragmentManager(), "acquireSettings"); } public void setNA(float na) { brightfieldNA = na; sendData(String.format("n, %d", (int) Math.round(na*100))); } public void setMultiModeDelay(float delay) { mmDelay = delay; } public void setDatasetName(String name) { datasetName = name; } public void toggleBrightfield() { sendData("c,4"); Camera.Parameters camParams = mCamera.getParameters(); camParams.setAutoExposureLock(false); mCamera.setParameters(camParams); } public void toggleDarkfield() { sendData("c,5"); Camera.Parameters camParams = mCamera.getParameters(); camParams.setAutoExposureLock(false); mCamera.setParameters(camParams); } public void toggleAlignment() { // TODO - add alignment routine sendData("x"); } //public native void FindFeatures(long matAddrGr, long matAddrRgba); }