我需要有关在 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
进行类型转换。
在Delphi中,
JList
和JArrayList
属于不同的接口层次结构,不能直接类型转换。问题出在下面一行
LContoursList:= JList(TJArrayList.JavaClass.init(0));
上面的强制类型转换将转换两个不兼容的接口,而不给您任何警告,然后当您尝试使用
LContoursList
时,它会崩溃。
如果您以安全的方式编写上述类型转换:
LContoursList := TJArrayList.Create as JList;
你会得到运行时异常,告诉你
JArrayList
不支持JList
接口。
异常类 EIntfCastError 并显示消息“接口不支持”。
由于底层 Java 类支持这两个接口,因此您可以使用以下代码进行不同的类型转换并将底层 Java 对象公开为
JList
:
var
LArr: JArrayList;
LContoursList: JList;
LArr := TJArrayList.Create;
LContoursList:= TJList.Wrap(LArr);