android - 在 Delphi 中使用 OpenCV for Android 会在使用 JList 时引发错误

标签 android opencv delphi firemonkey

我需要有关在 Android 上使用 OpenCV 的帮助(Git: https://github.com/CarlosHe/OpenCV-Android-Firemonkey ),轮廓示例。

我不知道如何使用轮廓列表(JList)? 我想循环遍历所有轮廓并将每个轮廓输出到 Memo1 中。

代码如下(返回错误“地址 C8E40F40 处的访问冲突,访问地址 47F027B5”):

    var
      LSrcMat: JMat;
      LDstMat: JMat;
      LHierarchyMat: JMat;
      LJBitmap: JBitmap;
      LThreshold: Double;
      LContoursList: JList;
      trash, maxval: Double;
      i, type_: Integer;
    begin
      FOpenCVInProgress := True;
      try
        trash := StrToFloat(edtTrash.Text);
        maxval := StrToFloat(edtMaxVal.Text);
        type_ := StrToInt(edtType.Text);
        LSrcMat := TJMat.JavaClass.init;
        LDstMat := TJMat.JavaClass.init;
        LHierarchyMat:= TJMat.JavaClass.init;
        LContoursList:= JList(TJArrayList.JavaClass.init(0));
        LJBitmap := TJBitmap.JavaClass.createBitmap(Trunc(FCamBitmap.Width), Trunc(FCamBitmap.Height), TJBitmap_Config.JavaClass.ARGB_8888);
        TJandroid_Utils.JavaClass.bitmapToMat(BitmapToJBitmap(FCamBitmap), LSrcMat);
        TJImgproc.JavaClass.cvtColor(LSrcMat, LDstMat, TJImgproc.JavaClass.COLOR_RGB2GRAY);   // change picture to gray
        LThreshold := TJImgproc.JavaClass.threshold(LDstMat, LDstMat, trash, maxval, type_);  // classify pixels into two different groups
        TJImgproc.JavaClass.Canny(LDstMat, LDstMat, LThreshold, LThreshold * 2);              // Edge detection
        TJImgproc.JavaClass.findContours(LDstMat, LContoursList, LHierarchyMat, TJImgproc.JavaClass.RETR_EXTERNAL, TJImgproc.JavaClass.CHAIN_APPROX_SIMPLE ); // find edge
        TJImgproc.JavaClass.cvtColor(LDstMat, LDstMat, TJImgproc.JavaClass.COLOR_GRAY2RGB);   // change picture to color
        TJImgproc.JavaClass.drawContours(LDstMat, LContoursList, -1, TJScalar.JavaClass.init(255,255,0) , 3);  // draw edge
        TJandroid_Utils.JavaClass.MatToBitmap(LDstMat, LJBitmap);
        FCamBitmap := JBitmapToBitmap(LJBitmap);
 // returns an error "Access violation at address C8E40F40, access address 47F027B5"
 For i := 0 to LContoursList.size - 1 do
 begin
         Memo1.Lines.Add(JStringToString((LContoursList.get(i).toString)));
 end;

最佳答案

您需要JList要传递给 findContours 的实例,但要得到JList例如,您无法从 JArrayList 对其进行类型转换就像你做的那样。

在德尔福 JListJArrayList属于不同的接口(interface)层次结构,不能直接类型转换。问题出在以下行

LContoursList:= JList(TJArrayList.JavaClass.init(0));

上面的强制类型转换将转换两个不兼容的接口(interface),而不给您任何警告,然后当您尝试使用 LContoursList 时它会崩溃。

如果您以安全的方式编写上述类型转换:

LContoursList := TJArrayList.Create as JList;

你会得到运行时异常,告诉你JArrayList不支持JList界面。

Exception class EIntfCastError with message 'Interface not supported'.

由于底层 Java 类支持这两个接口(interface),因此您可以进行不同的类型转换并将底层 Java 对象公开为 JList使用以下代码:

var
  LArr: JArrayList;
  LContoursList: JList;


  LArr := TJArrayList.Create;
  LContoursList:= TJList.Wrap(LArr);

注意:在 Delphi 中,如果你想调用默认的 Java 构造函数,你只需说 TJXXX.Create相反 TJXXX.JavaClass.init 。在您的情况下,调用容量为 0 的 Java 构造函数与使用默认构造函数没有太大区别。

注意:原始 FMX 示例在后台线程中运行。由于您尚未展示如何运行示例,因此如果您使用后台线程,则需要确保将 GUI 控件的任何使用与主线程同步。

关于android - 在 Delphi 中使用 OpenCV for Android 会在使用 JList 时引发错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77422784/

相关文章:

multithreading - 在没有 MyThread.Terminate 的情况下终止线程

Delphi:从 TBitbtn 显示/隐藏字形

sql - 查询不返回结果(Delphi、Oracle、DBExpress)

android - 如何在 Android TextView 中使用土耳其语字符(如 'ş ç ı ö')?

Android Span or Non-Breaking Space Causing line break and text duplication (4.0 ICS)

安卓目标 : not installed in Ubuntu

c++ - OpenCV Mat 到 alglib 真正的二维数组转换

c++ - OpenCV:获取 Mat 值的总和

安卓服务定时器

opencv - 为什么 dpkg 和 pkg-config 中 OpenCV 版本不同