我想在Android应用程序内部的图像上运行一些OpenCv过滤器。 我遇到了一个错误,我似乎无法找到原点。
Stacktrace:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources$Theme android.content.Context.getTheme()' on a null object reference
at android.app.AlertDialog.resolveDialogTheme(AlertDialog.java:222)
at android.app.AlertDialog$Builder.<init>(AlertDialog.java:452)
at org.opencv.android.BaseLoaderCallback.onPackageInstall(BaseLoaderCallback.java:90)
at org.opencv.android.AsyncServiceHelper.InstallService(AsyncServiceHelper.java:117)
at org.opencv.android.AsyncServiceHelper.initOpenCV(AsyncServiceHelper.java:33)
at org.opencv.android.OpenCVLoader.initAsync(OpenCVLoader.java:100)
at project.fragment.OpenCvTestFragment.onCreateView(OpenCvTestFragment.java:94)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
我的代码:(OpenCvTestFragment.java)
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
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.Size;
import org.opencv.imgproc.Imgproc;
import org.opencv.imgcodecs.Imgcodecs;
import java.io.IOException;
import team_excellence.growup.R;
public class OpenCvTestFragment extends Fragment implements CameraBridgeViewBase.CvCameraViewListener2, View.OnTouchListener {
private OnOpenCvTestInteractionListener mListener;
private View view;
private ImageView imgView1;
private ImageView imgView2;
public OpenCvTestFragment() {
}
public static OpenCvTestFragment newInstance(String param1, String param2) {
OpenCvTestFragment fragment = new OpenCvTestFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
private static final String TAG = "OCVSample::Activity";
private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(getActivity()) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS: {
Log.i(TAG, "OpenCV loaded successfully");
}
break;
default: {
super.onManagerConnected(status);
}
break;
}
}
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (container == null) {
return null;
}
view = inflater.inflate(R.layout.fragment_open_cv_test, container, false);
final ImageView imgView1 = (ImageView) view.findViewById(R.id.ocvImage1);
imgView1.setImageResource(R.drawable.img1);
ImageView imgView2 = (ImageView) view.findViewById(R.id.ocvImage2);
imgView1.setImageResource(R.drawable.img2);
final Button contoursButton = (Button) view.findViewById(R.id.contoursButton);
contoursButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
try {
applyContoursFilter("img1");
} catch (IOException e) {
e.printStackTrace();
}
}
});
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_8, getContext(),
mOpenCVCallBack);
return view;
}
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onOpenCvTestInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnOpenCvTestInteractionListener) {
mListener = (OnOpenCvTestInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnOpenCvTestInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
@Override
public void onCameraViewStarted(int width, int height) {
}
@Override
public void onCameraViewStopped() {
}
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
return null;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
public interface OnOpenCvTestInteractionListener {
void onOpenCvTestInteraction(Uri uri);
}
public void applyContoursFilter(String resName) throws IOException {
Mat matImg = convertImageToMat(resName);
Mat matResult = findContours(matImg);
Bitmap bm = Bitmap.createBitmap(matResult.cols(), matResult.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(matResult, bm);
imgView1.setImageBitmap(bm);
}
private Mat convertImageToMat(String resName) throws IOException {
int drawableResourceId = this.getResources().getIdentifier(resName, "drawable", getActivity().getPackageName());
Mat img = Utils.loadResource(getContext() , drawableResourceId , Imgcodecs.CV_LOAD_IMAGE_COLOR);
return img;
}
private Mat findContours (Mat image){
Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(19,19));
Mat closed = new Mat(); // closed will have type CV_32F
Imgproc.morphologyEx(image, closed, Imgproc.MORPH_CLOSE, kernel);
Core.divide(image, closed, closed, 1, CvType.CV_32F);
Core.normalize(closed, image, 0, 255, Core.NORM_MINMAX, CvType.CV_8U);
Imgproc.threshold(image, image, -1, 255, Imgproc.THRESH_BINARY_INV
+ Imgproc.THRESH_OTSU);
return closed;
}
}
为了说明按下相应的Button时,调用“applyContoursFilter”方法,然后将图像从drawables(显示在imgView1中)转换为Mat对象。 之后调用“findContours”方法,然后Mat-object转换回bmp格式并再次设置为imgView1。
那就是它应该如何运作。但上面发布的nullpointer错误被抛出,我无法弄清楚它来自何处或如何解决它。
我对Android比较陌生,非常感谢您的帮助。
答案 0 :(得分:0)
我现在通过在我的应用程序的MainActivity中初始化OpenCV并仅在片段中调用它来解决它。 我将BaseLoaderCallBack代码从Fragment的OnCreateView移动到MainActivity的OnCreate。 现在似乎工作正常。
答案 1 :(得分:0)
在我使用AlertDialog中的GPSTracker.this之前,我得到了一个例外&#39; android.content.res.Resources $ Theme android.content.Context.getTheme()&#39;
我通过添加这样的上下文解决了这个异常:
private final Context mContext;
public GPSTracker(Context context) {
this.mContext = context;
}
public void showSettingsAlert(String provider) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
...........
}