Android Studio:创建相机预览,检测矩形形状并提取它

如何解决Android Studio:创建相机预览,检测矩形形状并提取它

希望有人能帮我解决这个问题.. 我正在创建一个 android 应用程序,它应该打开相机,检测矩形形状并提取检测到的形状以进行进一步的图像处理和分析。基本上类似于这个线程:

how to extract an object from the camera preview android opencv

我也遇到了应该停止相机预览并返回检测到的形状(矩形)的问题。有没有人可以给我一些关于如何做到这一点的指导?

到目前为止我的代码

private Mat mHold = new Mat();
private Mat mRGB = new Mat();
private Mat mRGBF = new Mat();
private List<MatOfPoint> contours;


public MainActivity() {
    Log.i(TAG,"Instantiated new " + this.getClass());
}

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.activity_main);

    mOpenCvCameraview = (CameraBridgeView) findViewById(R.id.my_camera_view);
    mOpenCvCameraview.setMaxFrameSize(720,1280);
    mOpenCvCameraview.setVisibility(SurfaceView.VISIBLE);
    mOpenCvCameraview.setCvCameraviewListener(this);
}

@Override
public void onPause()
{
    super.onPause();
    if (mOpenCvCameraview != null)
        mOpenCvCameraview.disableView();
}

public void onResume()
{
    super.onResume();
    if (!OpenCVLoader.initDebug()) {
        Log.d("OpenCV","Internal OpenCV library not found. Using OpenCV Manager for initialization");
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION,this,mloaderCallback);
    } else {
        Log.d("OpenCV","OpenCV library found inside package. Using it!");
        mloaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
    }
}

public void onDestroy() {
    super.onDestroy();
    if (mOpenCvCameraview != null)
        mOpenCvCameraview.disableView();
}

public void onCameraviewStarted(int width,int height) {

    mRGB = new Mat(height,width,CvType.CV_8UC4);
    contours = new ArrayList<>();

}

public void onCameraviewStopped() {

    mRGB.release();

}

public Mat onCameraFrame(CvCameraviewFrame inputFrame)
{
    contours.clear();

    mRGB = inputFrame.rgba();

    mRGBF = mRGB.t();
    Core.flip(mRGB.t(),mRGBF,1);
    Imgproc.resize(mRGBF,mRGB.size()); //normal picture

    mHold = mRGB.t();
    Core.flip(mRGB.t(),mHold,1);
    Imgproc.resize(mHold,mRGB.size());


    //image- processing:
    Imgproc.cvtColor(mRGBF,Imgproc.COLOR_BGR2GRAY);
    Imgproc.GaussianBlur(mRGBF,new org.opencv.core.Size(1,1),2,2);
    Imgproc.Canny(mRGBF,50,50);
    //Imgproc.erode(mRGBF,new Mat());
    //Imgproc.dilate(mRGBF,new Mat());

    Imgproc.findContours(mRGBF,contours,new Mat(),Imgproc.RETR_EXTERNAL,Imgproc.CHAIN_APPROX_SIMPLE);
    Imgproc.drawContours(mHold,-1,new Scalar(255,0),2);

    double maxArea = -1;
    int maxAreaIdx = -1;
    MatOfPoint temp_contour = contours.get(0);
    MatOfPoint2f approxCurve = new MatOfPoint2f();
    Mat largest_contour = contours.get(0);
    List<MatOfPoint> largest_contours = new ArrayList<MatOfPoint>();
    for (int idx = 0; idx < contours.size(); idx++) {
        temp_contour = contours.get(idx);
        double contourarea = Imgproc.contourArea(temp_contour);
        //compare this contour to the prevIoUs largest contour found
        if (contourarea > maxArea) {
            //check if this contour is a square
            MatOfPoint2f new_mat = new MatOfPoint2f(temp_contour.toArray());
            int contourSize = (int)temp_contour.total();
            Imgproc.approxpolyDP(new_mat,approxCurve,contourSize*0.05,true);
            if (approxCurve.total() == 4) {
                    maxArea = contourarea;
                    maxAreaIdx = idx;
                    largest_contours.add(temp_contour);
                    largest_contour = temp_contour;
            }
        }
    }
    MatOfPoint temp_largest = largest_contours.get(largest_contours.size()-1);
    largest_contours = new ArrayList<MatOfPoint>();
    largest_contours.add(temp_largest);

    Mat emptyMat = Mat.zeros(mHold.size(),mHold.channels());
    Imgproc.drawContours(emptyMat,largest_contours,new Scalar(0,255,1);

返回 mHold;

基本上,onCameraFrame 返回突出显示所有轮廓的帧;现在我不太确定如何提取代表最大矩形的帧部分,从而终止预览。如您所见,我有一个想法,绘制一个 emptyMat 并将其转发到另一个活动,但它不起作用......我仍然不熟悉 android studio 的所有功能,因此非常感谢任何帮助。>

谢谢。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?