将 vector<dlib::p oint> 转换为 NSArray,以便将其传递给 Swift 类
Convert a vector<dlib::point> to an NSArray so it can be passed to a Swift class
我正在使用 dlib 的面部特征点检测器,并希望将面部特征点坐标存储在可在 Swift 中使用的数组中。
目前,我已经将地标坐标存储在一个向量中:
std::vector<dlib::point> facialLandmarks;
for (unsigned long k = 0; k < shape.num_parts(); k++) {
dlib::point p = shape.part(k);
facialLandmarks.push_back(p);
}
我现在想编写一个函数,将向量转换为 NSArray,以便我可以返回数组并在我的 Swift 代码中使用它。
当我尝试如下操作时:
NSArray* facialLandmarksArray = &facialLandmarks[0];
我收到一个错误:
Cannot initialize a variable of type 'NSArray *__strong' with an rvalue of type 'std::__1::__vector_base<dlib::vector<long, 2>, std::__1::allocator<dlib::vector<long, 2> > >::value_type *' (aka 'dlib::vector<long, 2> *')
我对Objective-C或C++知之甚少,但需要将其用于Dlib。任何帮助将不胜感激!
NSArray
只能包含Objective-C对象,不能包含C++对象。因此,您必须先将积分转换为NSValue
。这样的事情应该有效:
NSMutableArray* facialLandmarksArray = [NSMutableArray arrayWithCapacity: facialLandmarks.size()];
for (auto const& pt: facialLandmarks) {
[facialLandmarksArray addObject: [NSValue valueWithCGPoint:CGPointMake(pt.x, pt.y)]];
}
并确保将其编译为Objective-C++(文件结尾*.mm(。
但是,请注意,这对于大型矢量不能很好地缩放。Swift和C++都能够确保这些数组/向量的值存储在连续内存中,通过Objective-C桥接会破坏这个局部性。
这里的一些挑战是:
1( 我们希望尽量减少对地标点的复制,因为此类复制会影响软件性能和内存占用。
2( 我们如何在 Swift 代码中使用 C++vector
的成员,在本例中为dlib::point
类型的实例?
应对这些挑战取决于用例。 需要考虑的一些问题:
1( 性能/内存占用有多重要? 如果这不是问题,那么在将值提供给 Swift 时复制这些值是可以的。 当然,这也取决于C++代码是否必须使用 Swift 更改的值。
2(我们在谈论多少个里程碑点? 如果是一百分左右,那么复制它们不太可能是性能打击。
3( Swift 代码是只使用C++库返回的地标点的值,还是修改这些值并期望C++代码"看到"这些更改?
4( 通常,Swift 代码会访问每个地标点多少次? 如果每个点被多次访问,那么最好将所有点复制到可以在 Swift 中使用的结构中,而不是在每次访问时创建副本,而不是在每次 Swift 访问时都复制坐标。
5(可以容忍多少复杂性? 你愿意写很多C++代码吗? 您是否习惯在 Swift 中使用指针类型,例如UnsafeMutablePointer
?
以下是有关如何执行此操作的一些想法:
1( 在 Objective-C++ 中构造一个可以在 Swift 中使用的集合,并将地标点坐标值复制到该结构中。 @Tobi的回答就是一个例子。
2( 与上面的 (1( 类似,但 Swift 可访问的集合包含指向坐标值的指针。
3( 编写一个 Objective-C++ 类,其接口可从 Swift 访问,并且所有特定于C++的代码都隐藏在实现中。 该接口可以允许 Swift 代码读取(如果需要,还可以写入(特定地标点的特定坐标。
4( (3( 的变体,其中 Swift 代码访问指向坐标值的指针。 在 Swift 端使用这些坐标值时需要小心,以避免复制坐标值。
如果您提供有关用例的一些细节,我可以尝试举一个例子。
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- 复制列表初始化的隐式转换的等级是多少
- 正在将指针转换为范围
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 将 vector<dlib::p oint> 转换为 NSArray,以便将其传递给 Swift 类
- 将 std::string 转换为 Swift String
- 如何将元素从 Swift 中的 [UnsafeMutablePointer<UInt8>] 转换为 C++ 中的 UInt8 *