这是我的第一个android应用程序,我正在尝试制作一个实时矩形检测器,到目前为止,我已经成功了,我能够通过服务器将检测到的并裁剪的矩形的图像发送出去,但是我注意到接收到的图像质量很差。从研究中,我收集到CameraBridgeViewBase使用帧的(基于屏幕分辨率)图像,与相机的完整MP范围相比,该图像受到限制。我想知道是否有一种方法可以使用CameraBridgeViewBase显示处理过的帧,但是当用户按下按钮然后在其上应用矩形检测并将其发送出去时,获得照相机的完整MP质量。
下面是我的代码想法(不是实际的事情),我摆脱了其他行,因为它们很长,我认为这个问题可能很麻烦。相反,我在代码中添加了注释,这可能有助于解释我想做什么。 onCameraFrame已成功实现,我只需要在按下按钮时从摄像机获取完整的MP图像即可。非常感谢您的帮助。
package test.smartApp;
import android.Manifest;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.JavaCameraView;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
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.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.RotatedRect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import org.opencv.utils.Converters;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.lang.Math;
import java.util.Scanner;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import com.loopj.android.http.ResponseHandlerInterface;
import static android.os.SystemClock.sleep;
public class MainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2 {
//Camera parameters
public static final int MY_PERMISSIONS_REQUEST_CAMERA = 100;
public static final String ALLOW_KEY = "ALLOWED";
public static final String CAMERA_PREF = "camera_pref";
//view holder
JavaCameraView cameraBridgeViewBase;
//camera listener callback
BaseLoaderCallback baseLoaderCallback;
//image holder
Mat bwIMG, hsvIMG, lrrIMG, urrIMG, dsIMG, usIMG, cIMG, hovIMG;
MatOfPoint2f approxCurve;
Mat gray;
Mat dst;
ProgressDialog prgDialog;
RequestParams params = new RequestParams();
String imgPath, fileName;
Bitmap bitmap;
private static int RESULT_LOAD_IMG = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
prgDialog = new ProgressDialog(this);
// Set Cancelable as False
prgDialog.setCancelable(false);
// Capture our button from layout
FloatingActionButton sendBtn = findViewById(R.id.pictureButton);
sendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Get full camera MP image
//Convert to Mat
//Do processing on Mat
//Save Mat at Bitmap/Jpeg
}
});
cameraBridgeViewBase = findViewById(R.id.cameraViewer);
cameraBridgeViewBase.setVisibility(SurfaceView.VISIBLE);
cameraBridgeViewBase.setCvCameraViewListener(this);
//create camera listener callback
baseLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
Log.v("c-stick-log", "Loader interface success");
bwIMG = new Mat();
dsIMG = new Mat();
hsvIMG = new Mat();
lrrIMG = new Mat();
urrIMG = new Mat();
usIMG = new Mat();
cIMG = new Mat();
hovIMG = new Mat();
cameraBridgeViewBase.enableView();
break;
default:
super.onManagerConnected(status);
break;
}
}
};
}
@Override
public void onCameraViewStarted(int width, int height) {
if (ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED) {
if (getFromPref(this, ALLOW_KEY)) {
showSettingsAlert();
}
else if (ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CAMERA)) {
showAlert();
}
else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},MY_PERMISSIONS_REQUEST_CAMERA);
}
}
}
}
@Override
public void onCameraViewStopped() {
dst.release();
gray.release();
}
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
gray = inputFrame.gray();
dst = inputFrame.rgba();
// Do my processing here on frames.
// To be specific, the processing here is to find rectangles then crop them
// When a user presses the 'sendBtn' I will send a high resolution crop of the rectangle
return dst;
}
@Override
protected void onPause() {
super.onPause();
if (cameraBridgeViewBase != null) {
cameraBridgeViewBase.disableView();
}
}
@Override
protected void onResume() {
sleep(1000);
super.onResume();
if (!OpenCVLoader.initDebug()) {
Toast.makeText(getApplicationContext(), "There is a problem", Toast.LENGTH_SHORT).show();
} else {
baseLoaderCallback.onManagerConnected(BaseLoaderCallback.SUCCESS);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (cameraBridgeViewBase != null) {
cameraBridgeViewBase.disableView();
}
if (prgDialog != null) {
prgDialog.dismiss();
}
}
public static Boolean getFromPref(Context context, String key) {
SharedPreferences myPrefs = context.getSharedPreferences
(CAMERA_PREF, Context.MODE_PRIVATE);
return (myPrefs.getBoolean(key, false));
}
private void showAlert() {
AlertDialog alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle("Alert");
alertDialog.setMessage("App needs to access the Camera.");
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "DONT ALLOW",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
});
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "ALLOW",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.CAMERA},
MY_PERMISSIONS_REQUEST_CAMERA);
}
});
alertDialog.show();
}
private void showSettingsAlert() {
AlertDialog alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle("Alert");
alertDialog.setMessage("App needs to access the Camera.");
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "DONT ALLOW",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "SETTINGS",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
}