将 OpenCV 方法从 Java 重写为 C++

Rewrite OpenCV method from Java to C++

本文关键字:重写 C++ Java OpenCV 方法      更新时间:2023-10-16

谁能告诉我这段代码在C++中是什么样子的?我对java感到非常困惑,它是OpenCV的代表。

public static MatOfPoint convexHull(MatOfPoint contour) {
MatOfInt indexes = new MatOfInt();
Imgproc.convexHull(contour, indexes);
Point[] convexPoint = new Point[indexes.rows()];
double x, y;
int index;
for (int i = 0; i < indexes.rows(); i++) {
index = (int) indexes.get(i, 0)[0];
x = contour.get(index, 0)[0];
y = contour.get(index, 0)[1];
convexPoint[i] = new Point(x, y);
}
return new MatOfPoint(convexPoint);
}

到目前为止,我得到的是:

vector< Point > convexHull(vector< Point> & contour) {
vector<int> indexes;
convexHull(contour, indexes);
Point[] convexPoint = new Point[indexes.size()];
double x, y;
int index;
for (size_t i = 0; i < indexes.size(); i++) {
//I really don't understant what's going on here  
}
}

还有谁能解释一下那个java代码的for循环的主体?

循环根据Imgproc.convexHull返回的索引,用contour中的点填充convexPoint数组。

我不确定 Java,但在 C++ API 中,它毫无意义,因为当输出参数std::vector<cv::Point>时,cv::convexHull会很乐意为您执行此操作。

然后函数就变成了

std::vector<cv::Point> convexHull(std::vector<cv::Point> const& contour)
{
std::vector<cv::Point> result;
cv::convexHull(contour, result);
return result;
}

你是否需要它变得有些值得怀疑。

首先,我不明白为什么要将 java 代码转换为 c++,而它已经存在。查看您发布的代码(如果这是从某个地方复制的,在此处发布链接将非常有帮助)

public static MatOfPoint convexHull(MatOfPoint contour) {
MatOfInt indexes = new MatOfInt();
Imgproc.convexHull(contour, indexes);
Point[] convexPoint = new Point[indexes.rows()];
double x, y;
int index;
for (int i = 0; i < indexes.rows(); i++) {
index = (int) indexes.get(i, 0)[0];
x = contour.get(index, 0)[0];
y = contour.get(index, 0)[1];
convexPoint[i] = new Point(x, y);
}
return new MatOfPoint(convexPoint);
}

该代码正在调用 opencvImgproc.convexHull(contour,indexes)。它通过MatOfInt这意味着您将获得点的索引。现在,如果您仔细查看函数的返回值,您可以将其类型为MatOfPoint,并且在 for 循环中,我们正在从点索引构建返回对象。所以循环只是从索引转换为实际点。这是为了描述该代码中发生的情况。但让这一切变得奇怪的是,opencv C++(不确定 opencv/java 是否有这个)已经具有返回实际点的功能。你可以在这里查看关于凸壳函数的opencv官方文档

Opencv c++ convexHull 函数签名为:

void convexHull(InputArray points, OutputArray hull, bool clockwise=false, bool returnPoints=true )

参数说明为:

参数
– 输入 2D 点集,存储在 std::vector 或 Mat 中。船体– 输出凸包。它要么是索引的整数向量,要么是点的向量。在第一种情况下,包元素是原始数组中凸包点的从 0 开始的索引(因为凸包点集是原始点集的子集)。在第二种情况下,船体元素是凸包点本身。
顺时针– 方向标志。如果为 true,则输出凸包的方向为顺时针方向。否则,它逆时针方向。假定坐标系的 X 轴指向右侧,Y 轴指向上方。方向– 旧 API、CV_CLOCKWISE 或CV_COUNTERCLOCKWISE中的凸包方向参数。返回点– 操作标志。对于矩阵,当标志为 true 时,该函数返回凸包点。否则,它将返回凸包点的索引。当输出数组为 std::vector 时,该标志将被忽略,输出取决于向量的类型:std::vector 表示 returnPoints=true,std::vector 表示 returnPoints=false。

从参数描述中可以看出,如果将hull作为整数向量传递,则会返回索引。但是,如果您传递点向量,则会返回实际点而不是它们的索引。这正是您发布的函数正在做的事情。因此,与其转换为 c++,不如直接通过传递点向量来使用 opencv c++ 凸壳函数。