Unverified Commit 02385472 authored by Giles Payne's avatar Giles Payne Committed by GitHub
Browse files

Merge pull request #17165 from komakai:objc-binding

Objc binding

* Initial work on Objective-C wrapper

* Objective-C generator script; update manually generated wrappers

* Add Mat tests

* Core Tests

* Imgproc wrapper generation and tests

* Fixes for Imgcodecs wrapper

* Miscellaneous fixes. Swift build support

* Objective-C wrapper build/install

* Add Swift wrappers for videoio/objdetect/feature2d

* Framework build;iOS support

* Fix toArray functions;Use enum types whenever possible

* Use enum types where possible;prepare test build

* Update test

* Add test runner scripts for iOS and macOS

* Add test scripts and samples

* Build fixes

* Fix build (cmake 3.17.x compatibility)

* Fix warnings

* Fix enum name conflicting handling

* Add support for document generation with Jazzy

* Swift/Native fast accessor functions

* Add Objective-C wrapper for calib3d, dnn, ml, photo and video modules

* Remove IntOut/FloatOut/DoubleOut classes

* Fix iOS default test platform value

* Fix samples

* Revert default framework name to opencv2

* Add converter util functions

* Fix failing test

* Fix whitespace

* Add handling for deprecated methods;fix warnings;define __OPENCV_BUILD

* Suppress cmake warnings

* Reduce severity of "jazzy not found" log message

* Fix incorrect #include of compatibility header in ios.h

* Use explicit returns in subscript/get implementation

* Reduce minimum required cmake version to 3.15 for Objective-C/Swift binding
Showing with 1466 additions and 2 deletions
+1466 -2
......@@ -24,3 +24,4 @@ bin/
build
node_modules
CMakeSettings.json
xcuserdata/
......@@ -452,6 +452,7 @@ OCV_OPTION(BUILD_FAT_JAVA_LIB "Create Java wrapper exporting all functions
OCV_OPTION(BUILD_ANDROID_SERVICE "Build OpenCV Manager for Google Play" OFF IF ANDROID )
OCV_OPTION(BUILD_CUDA_STUBS "Build CUDA modules stubs when no CUDA SDK" OFF IF (NOT APPLE_FRAMEWORK) )
OCV_OPTION(BUILD_JAVA "Enable Java support" (ANDROID OR NOT CMAKE_CROSSCOMPILING) IF (ANDROID OR (NOT APPLE_FRAMEWORK AND NOT WINRT)) )
OCV_OPTION(BUILD_OBJC "Enable Objective-C support" ON IF APPLE_FRAMEWORK )
# OpenCV installation options
# ===================================================
......@@ -1595,6 +1596,12 @@ if(BUILD_JAVA)
status(" Java tests:" BUILD_TESTS AND opencv_test_java_BINARY_DIR THEN YES ELSE NO)
endif()
# ========================== Objective-C =======================
if(BUILD_OBJC)
status("")
status(" Objective-C wrappers:" HAVE_opencv_objc THEN YES ELSE NO)
endif()
ocv_cmake_hook(STATUS_DUMP_EXTRA)
# ========================== auxiliary ==========================
......
......@@ -30,6 +30,11 @@ if(BUILD_FAT_JAVA_LIB AND HAVE_opencv_java)
list(APPEND OPENCV_MODULES_CONFIGCMAKE opencv_java)
endif()
if(BUILD_OBJC AND HAVE_opencv_objc)
list(APPEND OPENCV_MODULES_CONFIGCMAKE opencv_objc)
endif()
# -------------------------------------------------------------------------------------------
# Part 1/3: ${BIN_DIR}/OpenCVConfig.cmake -> For use *without* "make install"
# -------------------------------------------------------------------------------------------
......
......@@ -788,6 +788,7 @@ macro(ocv_glob_module_sources)
if (APPLE)
file(GLOB_RECURSE lib_srcs_apple
"${CMAKE_CURRENT_LIST_DIR}/src/*.mm"
"${CMAKE_CURRENT_LIST_DIR}/src/*.swift"
)
list(APPEND lib_srcs ${lib_srcs_apple})
endif()
......
......@@ -7,5 +7,5 @@ if(DEBUG_opencv_calib3d)
list(APPEND debug_modules opencv_highgui)
endif()
ocv_define_module(calib3d opencv_imgproc opencv_features2d opencv_flann ${debug_modules}
WRAP java python js
WRAP java objc python js
)
{
"func_arg_fix" : {
"findCirclesGrid" : { "blobDetector" : {"defval" : "cv::SimpleBlobDetector::create()"} }
}
}
This diff is collapsed.
......@@ -19,7 +19,7 @@ ocv_add_dispatched_file_force_all(test_intrin512 TEST AVX512_SKX)
ocv_add_module(core
OPTIONAL opencv_cudev
WRAP java python js)
WRAP java objc python js)
set(extra_libs "")
......
//
// ArrayUtil.h
//
// Created by Giles Payne on 2020/02/09.
//
#pragma once
#import <Foundation/Foundation.h>
/**
* Utility function to create and populate an NSMutableArray with a specific size
* @param size Size of array to create
* @param val Value with which to initialize array elements
*/
NSMutableArray* createArrayWithSize(int size, NSObject* val);
//
// ArrayUtil.mm
//
// Created by Giles Payne on 2020/02/09.
//
#import "ArrayUtil.h"
NSMutableArray* createArrayWithSize(int size, NSObject* val) {
NSMutableArray *array = [NSMutableArray arrayWithCapacity:size];
for (int i = 0; i < size; i++){
[array addObject:val];
}
return array;
}
//
// ByteVector.h
//
// Created by Giles Payne on 2020/01/04.
//
#pragma once
#import <Foundation/Foundation.h>
#ifdef __cplusplus
#import <vector>
#endif
NS_ASSUME_NONNULL_BEGIN
/**
* Utility class to wrap a `std::vector<char>`
*/
@interface ByteVector : NSObject
#pragma mark - Constructors
/**
* Create ByteVector and initialize with the contents of an NSData object
* @param data NSData containing raw byte array
*/
-(instancetype)initWithData:(NSData*)data;
/**
* Create ByteVector and initialize with the contents of another ByteVector object
* @param src ByteVector containing data to copy
*/
-(instancetype)initWithVector:(ByteVector*)src;
#ifdef __OBJC__
/**
* Create ByteVector from raw C array
* @param array The raw C array
* @elements elements The number of elements in the array
*/
-(instancetype)initWithNativeArray:(char*)array elements:(NSInteger)elements;
#endif
#ifdef __cplusplus
/**
* Create ByteVector from std::vector<char>
* @param src The std::vector<char> object to wrap
*/
-(instancetype)initWithStdVector:(std::vector<char>&)src;
+(instancetype)fromNative:(std::vector<char>&)src;
#endif
#pragma mark - Properties
/**
* Length of the vector
*/
@property(readonly) NSInteger length;
#ifdef __OBJC__
/**
* Raw C array
*/
@property(readonly) char* nativeArray;
#endif
#ifdef __cplusplus
/**
* The wrapped std::vector<char> object
*/
@property(readonly) std::vector<char>& nativeRef;
#endif
/**
* NSData object containing the raw byte data
*/
@property(readonly) NSData* data;
#pragma mark - Accessor method
/**
* Return array element
* @param index Index of the array element to return
*/
-(char)get:(NSInteger)index;
@end
NS_ASSUME_NONNULL_END
//
// ByteVector.m
//
// Created by Giles Payne on 2020/01/04.
//
#import "ByteVector.h"
#import <vector>
@implementation ByteVector {
std::vector<char> v;
}
-(instancetype)initWithData:(NSData*)data {
self = [super init];
if (self) {
if (data.length % sizeof(char) != 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Invalid data length" userInfo:nil];
}
v.insert(v.begin(), (char*)data.bytes, (char*)data.bytes + data.length/sizeof(char));
}
return self;
}
-(instancetype)initWithVector:(ByteVector*)src {
self = [super init];
if (self) {
v.insert(v.begin(), src.nativeRef.begin(), src.nativeRef.end());
}
return self;
}
-(NSInteger)length {
return v.size();
}
-(char*)nativeArray {
return (char*)v.data();
}
-(instancetype)initWithNativeArray:(char*)array elements:(NSInteger)elements {
self = [super init];
if (self) {
v.insert(v.begin(), array, array + elements);
}
return self;
}
- (std::vector<char>&)nativeRef {
return v;
}
-(instancetype)initWithStdVector:(std::vector<char>&)src {
self = [super init];
if (self) {
v.insert(v.begin(), src.begin(), src.end());
}
return self;
}
+(instancetype)fromNative:(std::vector<char>&)src {
return [[ByteVector alloc] initWithStdVector:src];
}
-(char)get:(NSInteger)index {
if (index < 0 || index >= (long)v.size()) {
@throw [NSException exceptionWithName:NSRangeException reason:@"Invalid data length" userInfo:nil];
}
return v[index];
}
-(NSData*)data {
return [NSData dataWithBytesNoCopy:v.data() length:(v.size() * sizeof(char)) freeWhenDone:NO];
}
@end
//
// ByteVectorExt.swift
//
// Created by Giles Payne on 2020/01/04.
//
import Foundation
public extension ByteVector {
convenience init(_ array:[Int8]) {
let data = array.withUnsafeBufferPointer { Data(buffer: $0) }
self.init(data:data);
}
subscript(index: Int) -> Int8 {
get {
return self.get(index)
}
}
var array: [Int8] {
get {
var ret = Array<Int8>(repeating: 0, count: data.count/MemoryLayout<Int8>.stride)
_ = ret.withUnsafeMutableBytes { data.copyBytes(to: $0) }
return ret
}
}
}
extension ByteVector : Sequence {
public typealias Iterator = ByteVectorIterator
public func makeIterator() -> ByteVectorIterator {
return ByteVectorIterator(self)
}
}
public struct ByteVectorIterator: IteratorProtocol {
public typealias Element = Int8
let byteVector: ByteVector
var pos = 0
init(_ byteVector: ByteVector) {
self.byteVector = byteVector
}
mutating public func next() -> Int8? {
guard pos >= 0 && pos < byteVector.length
else { return nil }
pos += 1
return byteVector.get(pos - 1)
}
}
//
// CVObjcUtil.h
//
// Created by Giles Payne on 2020/01/02.
//
#pragma once
typedef union { double d; int64_t l; } V64;
typedef union { float f; int32_t i; } V32;
#define DOUBLE_TO_BITS(x) ((V64){ .d = x }).l
#define FLOAT_TO_BITS(x) ((V32){ .f = x }).i
#ifdef __cplusplus
#import <vector>
#define MAKE_PTR(t) (*((cv::Ptr<t>*)self.nativePtr))
template <typename CV, typename OBJC> std::vector<CV> objc2cv(NSArray<OBJC*>* _Nonnull array, CV& (* _Nonnull converter)(OBJC* _Nonnull)) {
std::vector<CV> ret;
for (OBJC* obj in array) {
ret.push_back(converter(obj));
}
return ret;
}
#define OBJC2CV(CV_CLASS, OBJC_CLASS, v, a) \
std::vector<CV_CLASS> v = objc2cv<CV_CLASS, OBJC_CLASS>(a, [](OBJC_CLASS* objc) -> CV_CLASS& { return objc.nativeRef; })
#define OBJC2CV_CUSTOM(CV_CLASS, OBJC_CLASS, v, a, CONV) \
std::vector<CV_CLASS> v; \
for (OBJC_CLASS* obj in a) { \
CV_CLASS tmp = CONV(obj); \
v.push_back(tmp); \
}
template <typename CV, typename OBJC> void cv2objc(std::vector<CV>& vector, NSMutableArray<OBJC*>* _Nonnull array, OBJC* _Nonnull (* _Nonnull converter)(CV&)) {
[array removeAllObjects];
for (size_t index = 0; index < vector.size(); index++) {
[array addObject:converter(vector[index])];
}
}
#define CV2OBJC(CV_CLASS, OBJC_CLASS, v, a) \
cv2objc<CV_CLASS, OBJC_CLASS>(v, a, [](CV_CLASS& cv) -> OBJC_CLASS* { return [OBJC_CLASS fromNative:cv]; })
#define CV2OBJC_CUSTOM(CV_CLASS, OBJC_CLASS, v, a, UNCONV) \
[a removeAllObjects]; \
for (size_t index = 0; index < v.size(); index++) { \
OBJC_CLASS *tmp = UNCONV(v[index]); \
[a addObject:tmp]; \
}
template <typename CV, typename OBJC> std::vector<std::vector<CV>> objc2cv2(NSArray<NSArray<OBJC*>*>* _Nonnull array, CV& (* _Nonnull converter)(OBJC* _Nonnull)) {
std::vector<std::vector<CV>> ret;
for (NSArray<OBJC*>* innerArray in array) {
std::vector<CV> innerVector;
for (OBJC* obj in innerArray) {
innerVector.push_back(converter(obj));
}
ret.push_back(innerVector);
}
return ret;
}
#define OBJC2CV2(CV_CLASS, OBJC_CLASS, v, a) \
std::vector<std::vector<CV_CLASS>> v = objc2cv2<CV_CLASS, OBJC_CLASS>(a, [](OBJC_CLASS* objc) -> CV_CLASS& { return objc.nativeRef; })
template <typename CV, typename OBJC> void cv2objc2(std::vector<std::vector<CV>>& vector, NSMutableArray<NSMutableArray<OBJC*>*>* _Nonnull array, OBJC* _Nonnull (* _Nonnull converter)(CV&)) {
[array removeAllObjects];
for (size_t index = 0; index < vector.size(); index++) {
std::vector<CV>& innerVector = vector[index];
NSMutableArray<OBJC*>* innerArray = [NSMutableArray arrayWithCapacity:innerVector.size()];
for (size_t index2 = 0; index2 < innerVector.size(); index2++) {
[innerArray addObject:converter(innerVector[index2])];
}
[array addObject:innerArray];
}
}
#define CV2OBJC2(CV_CLASS, OBJC_CLASS, v, a) \
cv2objc2<CV_CLASS, OBJC_CLASS>(v, a, [](CV_CLASS& cv) -> OBJC_CLASS* { return [OBJC_CLASS fromNative:cv]; })
#endif
//
// Converters.h
//
// Created by Giles Payne on 2020/03/03.
//
#pragma once
#ifdef __cplusplus
#import <opencv2/opencv.hpp>
#endif
#import <Foundation/Foundation.h>
#import "Mat.h"
#import "CvType.h"
#import "Point2i.h"
#import "Point2f.h"
#import "Point2d.h"
#import "Point3i.h"
#import "Point3f.h"
#import "Point3d.h"
#import "Rect2i.h"
#import "Rect2d.h"
#import "KeyPoint.h"
#import "DMatch.h"
#import "RotatedRect.h"
NS_ASSUME_NONNULL_BEGIN
@interface Converters : NSObject
+ (Mat*)vector_Point_to_Mat:(NSArray<Point2i*>*)pts NS_SWIFT_NAME(vector_Point_to_Mat(_:));
+ (NSArray<Point2i*>*)Mat_to_vector_Point:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_Point(_:));
+ (Mat*)vector_Point2f_to_Mat:(NSArray<Point2f*>*)pts NS_SWIFT_NAME(vector_Point2f_to_Mat(_:));
+ (NSArray<Point2f*>*)Mat_to_vector_Point2f:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_Point2f(_:));
+ (Mat*)vector_Point2d_to_Mat:(NSArray<Point2d*>*)pts NS_SWIFT_NAME(vector_Point2d_to_Mat(_:));
+ (NSArray<Point2f*>*)Mat_to_vector_Point2d:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_Point2d(_:));
+ (Mat*)vector_Point3i_to_Mat:(NSArray<Point3i*>*)pts NS_SWIFT_NAME(vector_Point3i_to_Mat(_:));
+ (NSArray<Point3i*>*)Mat_to_vector_Point3i:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_Point3i(_:));
+ (Mat*)vector_Point3f_to_Mat:(NSArray<Point3f*>*)pts NS_SWIFT_NAME(vector_Point3f_to_Mat(_:));
+ (NSArray<Point3f*>*)Mat_to_vector_Point3f:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_Point3f(_:));
+ (Mat*)vector_Point3d_to_Mat:(NSArray<Point3d*>*)pts NS_SWIFT_NAME(vector_Point3d_to_Mat(_:));
+ (NSArray<Point3d*>*)Mat_to_vector_Point3d:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_Point3d(_:));
+ (Mat*)vector_float_to_Mat:(NSArray<NSNumber*>*)fs NS_SWIFT_NAME(vector_float_to_Mat(_:));
+ (NSArray<NSNumber*>*)Mat_to_vector_float:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_float(_:));
+ (Mat*)vector_uchar_to_Mat:(NSArray<NSNumber*>*)us NS_SWIFT_NAME(vector_uchar_to_Mat(_:));
+ (NSArray<NSNumber*>*)Mat_to_vector_uchar:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_uchar(_:));
+ (Mat*)vector_char_to_Mat:(NSArray<NSNumber*>*)cs NS_SWIFT_NAME(vector_char_to_Mat(_:));
+ (NSArray<NSNumber*>*)Mat_to_vector_char:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_char(_:));
+ (Mat*)vector_int_to_Mat:(NSArray<NSNumber*>*)is NS_SWIFT_NAME(vector_int_to_Mat(_:));
+ (NSArray<NSNumber*>*)Mat_to_vector_int:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_int(_:));
+ (Mat*)vector_Rect_to_Mat:(NSArray<Rect2i*>*)rs NS_SWIFT_NAME(vector_Rect_to_Mat(_:));
+ (NSArray<Rect2i*>*)Mat_to_vector_Rect:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_Rect(_:));
+ (Mat*)vector_Rect2d_to_Mat:(NSArray<Rect2d*>*)rs NS_SWIFT_NAME(vector_Rect2d_to_Mat(_:));
+ (NSArray<Rect2d*>*)Mat_to_vector_Rect2d:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_Rect2d(_:));
+ (Mat*)vector_KeyPoint_to_Mat:(NSArray<KeyPoint*>*)kps NS_SWIFT_NAME(vector_KeyPoint_to_Mat(_:));
+ (NSArray<KeyPoint*>*)Mat_to_vector_KeyPoint:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_KeyPoint(_:));
+ (Mat*)vector_double_to_Mat:(NSArray<NSNumber*>*)ds NS_SWIFT_NAME(vector_double_to_Mat(_:));
+ (NSArray<NSNumber*>*)Mat_to_vector_double:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_double(_:));
+ (Mat*)vector_DMatch_to_Mat:(NSArray<DMatch*>*)matches NS_SWIFT_NAME(vector_DMatch_to_Mat(_:));
+ (NSArray<DMatch*>*)Mat_to_vector_DMatch:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_DMatch(_:));
+ (Mat*)vector_RotatedRect_to_Mat:(NSArray<RotatedRect*>*)rs NS_SWIFT_NAME(vector_RotatedRect_to_Mat(_:));
+ (NSArray<RotatedRect*>*)Mat_to_vector_RotatedRect:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_RotatedRect(_:));
@end
NS_ASSUME_NONNULL_END
//
// Converters.mm
//
// Created by Giles Payne on 31/05/2020.
//
#import "Converters.h"
#import "ArrayUtil.h"
#import "MatOfPoint2i.h"
#import "MatOfPoint2f.h"
#import "MatOfPoint3.h"
#import "MatOfPoint3f.h"
#import "MatOfFloat.h"
#import "MatOfByte.h"
#import "MatOfInt.h"
#import "MatOfDouble.h"
#import "MatOfRect2i.h"
#import "MatOfRect2d.h"
#import "MatOfKeyPoint.h"
#import "MatOfDMatch.h"
#import "MatOfRotatedRect.h"
@implementation Converters
+ (Mat*)vector_Point_to_Mat:(NSArray<Point2i*>*)pts {
return [[MatOfPoint2i alloc] initWithArray:pts];
}
+ (NSArray<Point2i*>*)Mat_to_vector_Point:(Mat*)mat {
return [[[MatOfPoint2i alloc] initWithMat:mat] toArray];
}
+ (Mat*)vector_Point2f_to_Mat:(NSArray<Point2f*>*)pts {
return [[MatOfPoint2f alloc] initWithArray:pts];
}
+ (NSArray<Point2f*>*)Mat_to_vector_Point2f:(Mat*)mat {
return [[[MatOfPoint2f alloc] initWithMat:mat] toArray];
}
+ (Mat*)vector_Point2d_to_Mat:(NSArray<Point2d*>*)pts {
Mat* res = [[Mat alloc] initWithRows:(int)pts.count cols:1 type:CV_64FC2];
NSMutableArray<NSNumber*>* buff = [NSMutableArray arrayWithCapacity:pts.count*2];
for (Point2d* pt in pts) {
[buff addObject:[NSNumber numberWithDouble:pt.x]];
[buff addObject:[NSNumber numberWithDouble:pt.y]];
}
[res put:0 col:0 data:buff];
return res;
}
+ (NSArray<Point2d*>*)Mat_to_vector_Point2d:(Mat*)mat {
if (mat.cols != 1 || mat.type != CV_64FC2) {
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Invalid Mat. Mat must be of type CV_64FC2 and have 1 column."]
userInfo:nil];
@throw exception;
}
NSMutableArray<Point2d*>* ret = [NSMutableArray new];
NSMutableArray<NSNumber*>* buff = createArrayWithSize(mat.rows*2, [NSNumber numberWithInt:0]);
[mat get:0 col:0 data:buff];
for (int i = 0; i < mat.rows; i++) {
[ret addObject:[[Point2d alloc] initWithX:buff[i * 2].doubleValue y:buff[i * 2 + 1].doubleValue]];
}
return ret;
}
+ (Mat*)vector_Point3i_to_Mat:(NSArray<Point3i*>*)pts {
return [[MatOfPoint3 alloc] initWithArray:pts];
}
+ (NSArray<Point3i*>*)Mat_to_vector_Point3i:(Mat*)mat {
return [[[MatOfPoint3 alloc] initWithMat:mat] toArray];
}
+ (Mat*)vector_Point3f_to_Mat:(NSArray<Point3f*>*)pts {
return [[MatOfPoint3f alloc] initWithArray:pts];
}
+ (NSArray<Point3f*>*)Mat_to_vector_Point3f:(Mat*)mat {
return [[[MatOfPoint3f alloc] initWithMat:mat] toArray];
}
+ (Mat*)vector_Point3d_to_Mat:(NSArray<Point3d*>*)pts {
Mat* res = [[Mat alloc] initWithRows:(int)pts.count cols:1 type:CV_64FC3];
NSMutableArray<NSNumber*>* buff = [NSMutableArray arrayWithCapacity:pts.count*3];
for (Point3d* pt in pts) {
[buff addObject:[NSNumber numberWithDouble:pt.x]];
[buff addObject:[NSNumber numberWithDouble:pt.y]];
[buff addObject:[NSNumber numberWithDouble:pt.z]];
}
[res put:0 col:0 data:buff];
return res;
}
+ (NSArray<Point3d*>*)Mat_to_vector_Point3d:(Mat*)mat {
if (mat.cols != 1 || mat.type != CV_64FC3) {
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Invalid Mat. Mat must be of type CV_64FC3 and have 1 column."]
userInfo:nil];
@throw exception;
}
NSMutableArray<Point3d*>* ret = [NSMutableArray new];
NSMutableArray<NSNumber*>* buff = createArrayWithSize(mat.rows*3, [NSNumber numberWithInt:0]);
[mat get:0 col:0 data:buff];
for (int i = 0; i < mat.rows; i++) {
[ret addObject:[[Point3d alloc] initWithX:buff[i * 3].doubleValue y:buff[i * 3 + 1].doubleValue z:buff[i * 3 + 2].doubleValue]];
}
return ret;
}
+ (Mat*)vector_float_to_Mat:(NSArray<NSNumber*>*)fs {
return [[MatOfFloat alloc] initWithArray:fs];
}
+ (NSArray<NSNumber*>*)Mat_to_vector_float:(Mat*)mat {
return [[[MatOfFloat alloc] initWithMat:mat] toArray];
}
+ (Mat*)vector_uchar_to_Mat:(NSArray<NSNumber*>*)us {
return [[MatOfByte alloc] initWithArray:us];
}
+ (NSArray<NSNumber*>*)Mat_to_vector_uchar:(Mat*)mat {
return [[[MatOfByte alloc] initWithMat:mat] toArray];
}
+ (Mat*)vector_char_to_Mat:(NSArray<NSNumber*>*)cs {
Mat* res = [[Mat alloc] initWithRows:(int)cs.count cols:1 type:CV_8S];
[res put:0 col:0 data:cs];
return res;
}
+ (NSArray<NSNumber*>*)Mat_to_vector_char:(Mat*)mat {
if (mat.cols != 1 || mat.type != CV_8S) {
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Invalid Mat. Mat must be of type CV_8S and have 1 column."]
userInfo:nil];
@throw exception;
}
NSMutableArray<NSNumber*>* ret = createArrayWithSize(mat.rows, @0);
[mat get:0 col:0 data:ret];
return ret;
}
+ (Mat*)vector_int_to_Mat:(NSArray<NSNumber*>*)is {
return [[MatOfInt alloc] initWithArray:is];
}
+ (NSArray<NSNumber*>*)Mat_to_vector_int:(Mat*)mat {
return [[[MatOfInt alloc] initWithMat:mat] toArray];
}
+ (Mat*)vector_Rect_to_Mat:(NSArray<Rect2i*>*)rs {
return [[MatOfRect2i alloc] initWithArray:rs];
}
+ (NSArray<Rect2i*>*)Mat_to_vector_Rect:(Mat*)mat {
return [[[MatOfRect2i alloc] initWithMat:mat] toArray];
}
+ (Mat*)vector_Rect2d_to_Mat:(NSArray<Rect2d*>*)rs {
return [[MatOfRect2d alloc] initWithArray:rs];
}
+ (NSArray<Rect2d*>*)Mat_to_vector_Rect2d:(Mat*)mat {
return [[[MatOfRect2d alloc] initWithMat:mat] toArray];
}
+ (Mat*)vector_KeyPoint_to_Mat:(NSArray<KeyPoint*>*)kps {
return [[MatOfKeyPoint alloc] initWithArray:kps];
}
+ (NSArray<KeyPoint*>*)Mat_to_vector_KeyPoint:(Mat*)mat {
return [[[MatOfKeyPoint alloc] initWithMat:mat] toArray];
}
+ (Mat*)vector_double_to_Mat:(NSArray<NSNumber*>*)ds {
return [[MatOfDouble alloc] initWithArray:ds];
}
+ (NSArray<NSNumber*>*)Mat_to_vector_double:(Mat*)mat {
return [[[MatOfDouble alloc] initWithMat:mat] toArray];
}
+ (Mat*)vector_DMatch_to_Mat:(NSArray<DMatch*>*)matches {
return [[MatOfDMatch alloc] initWithArray:matches];
}
+ (NSArray<DMatch*>*)Mat_to_vector_DMatch:(Mat*)mat {
return [[[MatOfDMatch alloc] initWithMat:mat] toArray];
}
+ (Mat*)vector_RotatedRect_to_Mat:(NSArray<RotatedRect*>*)rs {
return [[MatOfRotatedRect alloc] initWithArray:rs];
}
+ (NSArray<RotatedRect*>*)Mat_to_vector_RotatedRect:(Mat*)mat {
return [[[MatOfRotatedRect alloc] initWithMat:mat] toArray];
}
@end
//
// CvType.h
//
// Created by Giles Payne on 2019/10/13.
//
#ifdef __cplusplus
#import "opencv.hpp"
#endif
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Utility functions for handling CvType values
*/
@interface CvType : NSObject
#pragma mark - Type Utility functions
/**
* Create CvType value from depth and channel values
* @param depth Depth value. One of CV_8U, CV_8S, CV_16U, CV_16S, CV_32S, CV_32F or CV_64F
* @param channels Number of channels (from 1 to (CV_CN_MAX - 1))
*/
+ (int)makeType:(int)depth channels:(int)channels;
/**
* Get number of channels for type
* @param type Type value
*/
+ (int)channels:(int)type;
/**
* Get depth for type
* @param type Type value
*/
+ (int)depth:(int)type;
/**
* Get raw type size in bytes for type
* @param type Type value
*/
+ (int)rawTypeSize:(int)type;
/**
* Returns true if the raw type is an integer type (if depth is CV_8U, CV_8S, CV_16U, CV_16S or CV_32S)
* @param type Type value
*/
+ (BOOL)isInteger:(int)type;
/**
* Get element size in bytes for type
* @param type Type value
*/
+ (int)ELEM_SIZE:(int)type NS_SWIFT_NAME(elemSize(_:));
/**
* Get the string name for type
* @param type Type value
*/
+ (NSString*)typeToString:(int)type;
@end
NS_ASSUME_NONNULL_END
//
// CvType.m
//
// Created by Giles Payne on 2019/10/13.
//
#import "CvType.h"
@implementation CvType
+ (int)makeType:(int)depth channels:(int)channels {
if (channels <= 0 || channels >= CV_CN_MAX) {
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Channels count should be 1..%d", CV_CN_MAX - 1]
userInfo:nil];
@throw exception;
}
if (depth < 0 || depth >= CV_DEPTH_MAX) {
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Data type depth should be 0..%d", CV_DEPTH_MAX - 1]
userInfo:nil];
@throw exception;
}
return (depth & (CV_DEPTH_MAX - 1)) + ((channels - 1) << CV_CN_SHIFT);
}
+ (int)channels:(int)type {
return (type >> CV_CN_SHIFT) + 1;
}
+ (int)depth:(int)type {
return type & (CV_DEPTH_MAX - 1);
}
+ (BOOL)isInteger:(int)type {
return [CvType depth:type] < CV_32F;
}
+ (int)typeSizeBits:(int)type {
int depth = [CvType depth:type];
switch (depth) {
case CV_8U:
case CV_8S:
return 8;
case CV_16U:
case CV_16S:
case CV_16F:
return 16;
case CV_32S:
case CV_32F:
return 32;
case CV_64F:
return 64;
default:
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Unsupported CvType value: %d", type]
userInfo:nil];
@throw exception;
}
}
+ (int)rawTypeSize:(int)type {
return [CvType typeSizeBits:type] >> 3;
}
+ (char)typeMnenomic:(int)type {
int depth = [CvType depth:type];
switch (depth) {
case CV_8U:
case CV_16U:
return 'U';
case CV_8S:
case CV_16S:
case CV_32S:
return 'S';
case CV_16F:
case CV_32F:
case CV_64F:
return 'F';
default:
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Unsupported CvType value: %d", type]
userInfo:nil];
@throw exception;
}
}
+ (int)ELEM_SIZE:(int)type {
int typeSizeBytes = [CvType rawTypeSize:type];
return typeSizeBytes * [CvType channels:type];
}
+ (NSString*)typeToString:(int)type {
int typeSizeBits = [CvType typeSizeBits:type];
char typeMnenomic = [CvType typeMnenomic:type];
int channels = [CvType channels:type];
NSString* channelsSuffix = [NSString stringWithFormat:(channels <= 4)?@"%d":@"(%d)", channels];
return [NSString stringWithFormat:@"CV_%d%cC%@", typeSizeBits, typeMnenomic, channelsSuffix];
}
@end
//
// CvTypeExt.swift
//
// Created by Giles Payne on 2020/01/19.
//
import Foundation
public extension CvType {
static let CV_8U: Int32 = 0
static let CV_8S: Int32 = 1
static let CV_16U: Int32 = 2
static let CV_16S: Int32 = 3
static let CV_32S: Int32 = 4
static let CV_32F: Int32 = 5
static let CV_64F: Int32 = 6
static let CV_16F: Int32 = 7
static let CV_8UC1: Int32 = CV_8UC(1)
static let CV_8UC2: Int32 = CV_8UC(2)
static let CV_8UC3: Int32 = CV_8UC(3)
static let CV_8UC4: Int32 = CV_8UC(4)
static let CV_8SC1: Int32 = CV_8SC(1)
static let CV_8SC2: Int32 = CV_8SC(2)
static let CV_8SC3: Int32 = CV_8SC(3)
static let CV_8SC4: Int32 = CV_8SC(4)
static let CV_16UC1: Int32 = CV_16UC(1)
static let CV_16UC2: Int32 = CV_16UC(2)
static let CV_16UC3: Int32 = CV_16UC(3)
static let CV_16UC4: Int32 = CV_16UC(4)
static let CV_16SC1: Int32 = CV_16SC(1)
static let CV_16SC2: Int32 = CV_16SC(2)
static let CV_16SC3: Int32 = CV_16SC(3)
static let CV_16SC4: Int32 = CV_16SC(4)
static let CV_32SC1: Int32 = CV_32SC(1)
static let CV_32SC2: Int32 = CV_32SC(2)
static let CV_32SC3: Int32 = CV_32SC(3)
static let CV_32SC4: Int32 = CV_32SC(4)
static let CV_32FC1: Int32 = CV_32FC(1)
static let CV_32FC2: Int32 = CV_32FC(2)
static let CV_32FC3: Int32 = CV_32FC(3)
static let CV_32FC4: Int32 = CV_32FC(4)
static let CV_64FC1: Int32 = CV_64FC(1)
static let CV_64FC2: Int32 = CV_64FC(2)
static let CV_64FC3: Int32 = CV_64FC(3)
static let CV_64FC4: Int32 = CV_64FC(4)
static let CV_16FC1: Int32 = CV_16FC(1)
static let CV_16FC2: Int32 = CV_16FC(2)
static let CV_16FC3: Int32 = CV_16FC(3)
static let CV_16FC4: Int32 = CV_16FC(4)
static let CV_CN_MAX = 512
static let CV_CN_SHIFT = 3
static let CV_DEPTH_MAX = 1 << CV_CN_SHIFT
static func CV_8UC(_ channels:Int32) -> Int32 {
return make(CV_8U, channels: channels)
}
static func CV_8SC(_ channels:Int32) -> Int32 {
return make(CV_8S, channels: channels)
}
static func CV_16UC(_ channels:Int32) -> Int32 {
return make(CV_16U, channels: channels)
}
static func CV_16SC(_ channels:Int32) -> Int32 {
return make(CV_16S, channels: channels)
}
static func CV_32SC(_ channels:Int32) -> Int32 {
return make(CV_32S, channels: channels)
}
static func CV_32FC(_ channels:Int32) -> Int32 {
return make(CV_32F, channels: channels)
}
static func CV_64FC(_ channels:Int32) -> Int32 {
return make(CV_64F, channels: channels)
}
static func CV_16FC(_ channels:Int32) -> Int32 {
return make(CV_16F, channels: channels)
}
}
//
// DMatch.h
//
// Created by Giles Payne on 2019/12/25.
//
#pragma once
#ifdef __cplusplus
#import "opencv.hpp"
#endif
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Structure for matching: query descriptor index, train descriptor index, train
* image index and distance between descriptors.
*/
@interface DMatch : NSObject
/**
* Query descriptor index.
*/
@property int queryIdx;
/**
* Train descriptor index.
*/
@property int trainIdx;
/**
* Train image index.
*/
@property int imgIdx;
/**
* Distance
*/
@property float distance;
#ifdef __cplusplus
@property(readonly) cv::DMatch& nativeRef;
#endif
- (instancetype)init;
- (instancetype)initWithQueryIdx:(int)queryIdx trainIdx:(int)trainIdx distance:(float)distance;
- (instancetype)initWithQueryIdx:(int)queryIdx trainIdx:(int)trainIdx imgIdx:(int)imgIdx distance:(float)distance;
#ifdef __cplusplus
+ (instancetype)fromNative:(cv::DMatch&)dMatch;
#endif
/**
* Distance comparison
* @param it DMatch object to compare
*/
- (BOOL)lessThan:(DMatch*)it;
/**
* Clone object
*/
- (DMatch*)clone;
/**
* Compare for equality
* @param other Object to compare
*/
- (BOOL)isEqual:(nullable id)other;
/**
* Calculate hash for this object
*/
- (NSUInteger)hash;
/**
* Returns a string that describes the contents of the object
*/
- (NSString*)description;
@end
NS_ASSUME_NONNULL_END
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment