将 OpenCV 方法从 Java 重写为 C++
Rewrite OpenCV method from Java to C++
谁能告诉我这段代码在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++ 凸壳函数。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 将OpenCV C++重写为EmguCV C#-如何使用指针
- 在 C++ 中用派生类型重写成员函数
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 方法重写线程C++中的概念
- 为重写std::exception的库生成swig接口时出错
- 如何强制从重写方法调用重写的方法基方法?
- 用于C++的静态二进制检测或二进制重写工具和框架
- 如何将 if else 语句重写为 switch 语句
- 如何重写全局方法名称以在调用原始方法之前将我的代码推到前面
- 用 C 重写C++类
- 是否总是可以将使用递归编写的程序重写为不使用递归的程序C++,性能观点是什么?
- 重写虚拟函数和继承
- C++调用使用重写函数的父类函数
- 重写打印函数而不是覆盖基类
- 不允许在类定义之外重写
- C++有没有办法强制重写一组方法,如果其中一个方法在子类中具有重写?
- C++:从抽象类重写纯虚拟运算符重载
- 派生类调用父类的方法,该方法调用重写的虚拟方法调用错误的方法
- 重写函数不打印基类数据