feat: 切换后端至PaddleOCR-NCNN,切换工程为CMake

1.项目后端整体迁移至PaddleOCR-NCNN算法,已通过基本的兼容性测试
2.工程改为使用CMake组织,后续为了更好地兼容第三方库,不再提供QMake工程
3.重整权利声明文件,重整代码工程,确保最小化侵权风险

Log: 切换后端至PaddleOCR-NCNN,切换工程为CMake
Change-Id: I4d5d2c5d37505a4a24b389b1a4c5d12f17bfa38c
This commit is contained in:
wangzhengyang
2022-05-10 09:54:44 +08:00
parent ecdd171c6f
commit 718c41634f
10018 changed files with 3593797 additions and 186748 deletions

View File

@ -0,0 +1,16 @@
//
// 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);

View File

@ -0,0 +1,15 @@
//
// 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;
}

View File

@ -0,0 +1,89 @@
//
// ByteVector.h
//
// Created by Giles Payne on 2020/01/04.
//
#pragma once
#import <Foundation/Foundation.h>
#ifdef __cplusplus
#import <vector>
#endif
#import "CVObjcUtil.h"
NS_ASSUME_NONNULL_BEGIN
/**
* Utility class to wrap a `std::vector<char>`
*/
CV_EXPORTS @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

View File

@ -0,0 +1,76 @@
//
// 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

View File

@ -0,0 +1,66 @@
//
// 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);
}
convenience init(_ array:[UInt8]) {
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
}
}
var unsignedArray: [UInt8] {
get {
var ret = Array<UInt8>(repeating: 0, count: data.count/MemoryLayout<UInt8>.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)
}
}

View File

@ -0,0 +1,85 @@
//
// CVObjcUtil.h
//
// Created by Giles Payne on 2020/01/02.
//
#pragma once
#ifndef CV_EXPORTS
#ifdef __cplusplus
#define CV_EXPORTS __attribute__ ((visibility ("default")))
#else
#define CV_EXPORTS
#endif
#endif
#ifdef __cplusplus
#import <vector>
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

View File

@ -0,0 +1,100 @@
//
// Converters.h
//
// Created by Giles Payne on 2020/03/03.
//
#pragma once
#ifdef __cplusplus
#import <opencv2/core.hpp>
#else
#define CV_EXPORTS
#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
CV_EXPORTS @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<Point2d*>*)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

View File

@ -0,0 +1,205 @@
//
// 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

View File

@ -0,0 +1,69 @@
//
// CvType.h
//
// Created by Giles Payne on 2019/10/13.
//
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Utility functions for handling CvType values
*/
CV_EXPORTS @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

View File

@ -0,0 +1,105 @@
//
// 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

View File

@ -0,0 +1,90 @@
//
// 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)
}
}

View File

@ -0,0 +1,84 @@
//
// DMatch.h
//
// Created by Giles Payne on 2019/12/25.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#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.
*/
CV_EXPORTS @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

View File

@ -0,0 +1,108 @@
//
// DMatch.m
//
// Created by Giles Payne on 2019/12/25.
//
#import "DMatch.h"
@implementation DMatch {
cv::DMatch native;
}
- (int)queryIdx {
return native.queryIdx;
}
- (void)setQueryIdx:(int)queryIdx {
native.queryIdx = queryIdx;
}
- (int)trainIdx {
return native.trainIdx;
}
- (void)setTrainIdx:(int)trainIdx {
native.trainIdx = trainIdx;
}
- (int)imgIdx {
return native.imgIdx;
}
- (void)setImgIdx:(int)imgIdx {
native.imgIdx = imgIdx;
}
- (float)distance {
return native.distance;
}
- (void)setDistance:(float)distance {
native.distance = distance;
}
- (cv::DMatch&)nativeRef {
return native;
}
- (instancetype)init {
return [self initWithQueryIdx:-1 trainIdx:-1 distance:FLT_MAX];
}
- (instancetype)initWithQueryIdx:(int)queryIdx trainIdx:(int)trainIdx distance:(float)distance {
return [self initWithQueryIdx:queryIdx trainIdx:trainIdx imgIdx:-1 distance:distance];
}
- (instancetype)initWithQueryIdx:(int)queryIdx trainIdx:(int)trainIdx imgIdx:(int)imgIdx distance:(float)distance {
self = [super init];
if (self != nil) {
self.queryIdx = queryIdx;
self.trainIdx = trainIdx;
self.imgIdx = imgIdx;
self.distance = distance;
}
return self;
}
+ (instancetype)fromNative:(cv::DMatch&)dMatch {
return [[DMatch alloc] initWithQueryIdx:dMatch.queryIdx trainIdx:dMatch.trainIdx imgIdx:dMatch.imgIdx distance:dMatch.distance];
}
- (BOOL)lessThan:(DMatch*)it {
return self.distance < it.distance;
}
- (DMatch*)clone {
return [[DMatch alloc] initWithQueryIdx:self.queryIdx trainIdx:self.trainIdx imgIdx:self.imgIdx distance:self.distance];
}
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
} else if (![other isKindOfClass:[DMatch class]]) {
return NO;
} else {
DMatch* dMatch = (DMatch*)other;
return self.queryIdx == dMatch.queryIdx && self.trainIdx == dMatch.trainIdx && self.imgIdx == dMatch.imgIdx && self.distance == dMatch.distance;
}
}
#define FLOAT_TO_BITS(x) ((Cv32suf){ .f = x }).i
- (NSUInteger)hash {
int prime = 31;
uint32_t result = 1;
result = prime * result + self.queryIdx;
result = prime * result + self.trainIdx;
result = prime * result + self.imgIdx;
result = prime * result + FLOAT_TO_BITS(self.distance);
return result;
}
- (NSString *)description {
return [NSString stringWithFormat:@"DMatch { queryIdx: %d, trainIdx: %d, imgIdx: %d, distance: %f}", self.queryIdx, self.trainIdx, self.imgIdx, self.distance];
}
@end

View File

@ -0,0 +1,90 @@
//
// Double2.h
//
// Created by Giles Payne on 2020/05/22.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
#import <Foundation/Foundation.h>
@class Mat;
NS_ASSUME_NONNULL_BEGIN
/**
* Simple wrapper for a vector of two `double`
*/
CV_EXPORTS @interface Double2 : NSObject
#pragma mark - Properties
/**
* First vector element
*/
@property double v0;
/**
* Second vector element
*/
@property double v1;
#ifdef __cplusplus
/**
* The wrapped vector
*/
@property(readonly) cv::Vec2d& nativeRef;
#endif
#pragma mark - Constructors
/**
* Create zero-initialize vecior
*/
-(instancetype)init;
/**
* Create vector with specified element values
* @param v0 First element
* @param v1 Second element
*/
-(instancetype)initWithV0:(double)v0 v1:(double)v1;
/**
* Create vector with specified element values
* @param vals array of element values
*/
-(instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#ifdef __cplusplus
+(instancetype)fromNative:(cv::Vec2d&)vec2d;
#endif
/**
* Update vector with specified element values
* @param vals array of element values
*/
-(void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
/**
* Get vector as an array
*/
-(NSArray<NSNumber*>*)get;
#pragma mark - Common Methods
/**
* Compare for equality
* @param other Object to compare
*/
-(BOOL)isEqual:(nullable id)other;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,75 @@
//
// Double2.mm
//
// Created by Giles Payne on 2020/05/22.
//
#import "Double2.h"
#import "Mat.h"
@implementation Double2 {
cv::Vec2d native;
}
-(double)v0 {
return native[0];
}
-(void)setV0:(double)v {
native[0] = v;
}
-(double)v1 {
return native[1];
}
-(void)setV1:(double)v {
native[1] = v;
}
-(instancetype)init {
return [self initWithV0:0 v1:0];
}
-(instancetype)initWithV0:(double)v0 v1:(double)v1 {
self = [super init];
if (self) {
self.v0 = v0;
self.v1 = v1;
}
return self;
}
-(instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
self = [super init];
if (self) {
[self set:vals];
}
return self;
}
+(instancetype)fromNative:(cv::Vec2d&)vec2d {
return [[Double2 alloc] initWithV0:vec2d[0] v1:vec2d[1]];
}
-(void)set:(NSArray<NSNumber*>*)vals {
self.v0 = (vals != nil && vals.count > 0) ? vals[0].doubleValue : 0;
self.v1 = (vals != nil && vals.count > 1) ? vals[1].doubleValue : 0;
}
-(NSArray<NSNumber*>*)get {
return @[[NSNumber numberWithFloat:native[0]], [NSNumber numberWithFloat:native[1]]];
}
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
} else if (![other isKindOfClass:[Double2 class]]) {
return NO;
} else {
Double2* d2 = (Double2*)other;
return self.v0 == d2.v0 && self.v1 == d2.v1;
}
}
@end

View File

@ -0,0 +1,96 @@
//
// Double3.h
//
// Created by Giles Payne on 2020/05/22.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
#import <Foundation/Foundation.h>
@class Mat;
NS_ASSUME_NONNULL_BEGIN
/**
* Simple wrapper for a vector of three `double`
*/
CV_EXPORTS @interface Double3 : NSObject
#pragma mark - Properties
/**
* First vector element
*/
@property double v0;
/**
* Second vector element
*/
@property double v1;
/**
* Third vector element
*/
@property double v2;
#ifdef __cplusplus
/**
* The wrapped vector
*/
@property(readonly) cv::Vec3d& nativeRef;
#endif
#pragma mark - Constructors
/**
* Create zero-initialize vecior
*/
-(instancetype)init;
/**
* Create vector with specified element values
* @param v0 First element
* @param v1 Second element
* @param v2 Third element
*/
-(instancetype)initWithV0:(double)v0 v1:(double)v1 v2:(double)v2;
/**
* Create vector with specified element values
* @param vals array of element values
*/
-(instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#ifdef __cplusplus
+(instancetype)fromNative:(cv::Vec3d&)vec3d;
#endif
/**
* Update vector with specified element values
* @param vals array of element values
*/
-(void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
/**
* Get vector as an array
*/
-(NSArray<NSNumber*>*)get;
#pragma mark - Common Methods
/**
* Compare for equality
* @param other Object to compare
*/
-(BOOL)isEqual:(nullable id)other;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,85 @@
//
// Double3.mm
//
// Created by Giles Payne on 2020/05/22.
//
#import "Double3.h"
#import "Mat.h"
@implementation Double3 {
cv::Vec3d native;
}
-(double)v0 {
return native[0];
}
-(void)setV0:(double)v {
native[0] = v;
}
-(double)v1 {
return native[1];
}
-(void)setV1:(double)v {
native[1] = v;
}
-(double)v2 {
return native[2];
}
-(void)setV2:(double)v {
native[2] = v;
}
-(instancetype)init {
return [self initWithV0:0 v1:0 v2:0];
}
-(instancetype)initWithV0:(double)v0 v1:(double)v1 v2:(double)v2 {
self = [super init];
if (self) {
self.v0 = v0;
self.v1 = v1;
self.v2 = v2;
}
return self;
}
-(instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
self = [super init];
if (self) {
[self set:vals];
}
return self;
}
+(instancetype)fromNative:(cv::Vec3d&)vec3d {
return [[Double3 alloc] initWithV0:vec3d[0] v1:vec3d[1] v2:vec3d[2]];
}
-(void)set:(NSArray<NSNumber*>*)vals {
self.v0 = (vals != nil && vals.count > 0) ? vals[0].doubleValue : 0;
self.v1 = (vals != nil && vals.count > 1) ? vals[1].doubleValue : 0;
self.v2 = (vals != nil && vals.count > 2) ? vals[2].doubleValue : 0;
}
-(NSArray<NSNumber*>*)get {
return @[[NSNumber numberWithFloat:native[0]], [NSNumber numberWithFloat:native[1]], [NSNumber numberWithFloat:native[2]]];
}
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
} else if (![other isKindOfClass:[Double3 class]]) {
return NO;
} else {
Double3* d3 = (Double3*)other;
return self.v0 == d3.v0 && self.v1 == d3.v1 && self.v2 == d3.v2;
}
}
@end

View File

@ -0,0 +1,89 @@
//
// DoubleVector.h
//
// Created by Giles Payne on 2020/01/04.
//
#pragma once
#import <Foundation/Foundation.h>
#ifdef __cplusplus
#import <vector>
#endif
#import "CVObjcUtil.h"
NS_ASSUME_NONNULL_BEGIN
/**
* Utility class to wrap a `std::vector<double>`
*/
CV_EXPORTS @interface DoubleVector : NSObject
#pragma mark - Constructors
/**
* Create DoubleVector and initialize with the contents of an NSData object
* @param data NSData containing raw double array
*/
-(instancetype)initWithData:(NSData*)data;
/**
* Create DoubleVector and initialize with the contents of another DoubleVector object
* @param src DoubleVector containing data to copy
*/
-(instancetype)initWithVector:(DoubleVector*)src;
#ifdef __OBJC__
/**
* Create DoubleVector from raw C array
* @param array The raw C array
* @elements elements The number of elements in the array
*/
-(instancetype)initWithNativeArray:(double*)array elements:(int)elements;
#endif
#ifdef __cplusplus
/**
* Create DoubleVector from std::vector<double>
* @param src The std::vector<double> object to wrap
*/
-(instancetype)initWithStdVector:(std::vector<double>&)src;
+(instancetype)fromNative:(std::vector<double>&)src;
#endif
#pragma mark - Properties
/**
* Length of the vector
*/
@property(readonly) size_t length;
#ifdef __OBJC__
/**
* Raw C array
*/
@property(readonly) double* nativeArray;
#endif
#ifdef __cplusplus
/**
* The wrapped std::vector<double> object
*/
@property(readonly) std::vector<double>& nativeRef;
#endif
/**
* NSData object containing the raw double data
*/
@property(readonly) NSData* data;
#pragma mark - Accessor method
/**
* Return array element
* @param index Index of the array element to return
*/
-(double)get:(NSInteger)index;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,76 @@
//
// DoubleVector.m
//
// Created by Giles Payne on 2020/01/04.
//
#import "DoubleVector.h"
#import <vector>
@implementation DoubleVector {
std::vector<double> v;
}
-(instancetype)initWithData:(NSData*)data {
self = [super init];
if (self) {
if (data.length % sizeof(double) != 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Invalid data length" userInfo:nil];
}
v.insert(v.begin(), (double*)data.bytes, (double*)data.bytes + data.length/sizeof(double));
}
return self;
}
-(instancetype)initWithVector:(DoubleVector*)src {
self = [super init];
if (self) {
v.insert(v.begin(), src.nativeRef.begin(), src.nativeRef.end());
}
return self;
}
-(size_t)length {
return v.size();
}
-(double*)nativeArray {
return (double*)v.data();
}
-(instancetype)initWithNativeArray:(double*)array elements:(int)elements {
self = [super init];
if (self) {
v.insert(v.begin(), array, array + elements);
}
return self;
}
- (std::vector<double>&)nativeRef {
return v;
}
-(instancetype)initWithStdVector:(std::vector<double>&)src {
self = [super init];
if (self) {
v.insert(v.begin(), src.begin(), src.end());
}
return self;
}
+(instancetype)fromNative:(std::vector<double>&)src {
return [[DoubleVector alloc] initWithStdVector:src];
}
-(double)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(double)) freeWhenDone:NO];
}
@end

View File

@ -0,0 +1,53 @@
//
// DoubleVectorExt.swift
//
// Created by Giles Payne on 2020/01/04.
//
import Foundation
public extension DoubleVector {
convenience init(_ array:[Double]) {
let data = array.withUnsafeBufferPointer { Data(buffer: $0) }
self.init(data:data);
}
subscript(index: Int) -> Double {
get {
return self.get(index)
}
}
var array: [Double] {
get {
var ret = Array<Double>(repeating: 0, count: data.count/MemoryLayout<Double>.stride)
_ = ret.withUnsafeMutableBytes { data.copyBytes(to: $0) }
return ret
}
}
}
extension DoubleVector : Sequence {
public typealias Iterator = DoubleVectorIterator
public func makeIterator() -> DoubleVectorIterator {
return DoubleVectorIterator(self)
}
}
public struct DoubleVectorIterator: IteratorProtocol {
public typealias Element = Double
let doubleVector: DoubleVector
var pos = 0
init(_ doubleVector: DoubleVector) {
self.doubleVector = doubleVector
}
mutating public func next() -> Double? {
guard pos >= 0 && pos < doubleVector.length
else { return nil }
pos += 1
return doubleVector.get(pos - 1)
}
}

View File

@ -0,0 +1,101 @@
//
// Float4.h
//
// Created by Giles Payne on 2020/02/05.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@class Mat;
/**
* Simple wrapper for a vector of four `float`
*/
CV_EXPORTS @interface Float4 : NSObject
#pragma mark - Properties
/**
* First vector element
*/
@property float v0;
/**
* Second vector element
*/
@property float v1;
/**
* Third vector element
*/
@property float v2;
/**
* Fourth vector element
*/
@property float v3;
#ifdef __cplusplus
/**
* The wrapped vector
*/
@property(readonly) cv::Vec4f& nativeRef;
#endif
#pragma mark - Constructors
/**
* Create zero-initialize vecior
*/
-(instancetype)init;
/**
* Create vector with specified element values
* @param v0 First element
* @param v1 Second element
* @param v2 Third element
* @param v3 Fourth element
*/
-(instancetype)initWithV0:(float)v0 v1:(float)v1 v2:(float)v2 v3:(float)v3;
/**
* Create vector with specified element values
* @param vals array of element values
*/
-(instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#ifdef __cplusplus
+(instancetype)fromNative:(cv::Vec4f&)vec4f;
#endif
/**
* Update vector with specified element values
* @param vals array of element values
*/
-(void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
/**
* Get vector as an array
*/
-(NSArray<NSNumber*>*)get;
#pragma mark - Common Methods
/**
* Compare for equality
* @param other Object to compare
*/
-(BOOL)isEqual:(nullable id)other;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,95 @@
//
// Float4.mm
//
// Created by Giles Payne on 2020/02/05.
//
#import "Float4.h"
#import "Mat.h"
@implementation Float4 {
cv::Vec4f native;
}
-(float)v0 {
return native[0];
}
-(void)setV0:(float)v {
native[0] = v;
}
-(float)v1 {
return native[1];
}
-(void)setV1:(float)v {
native[1] = v;
}
-(float)v2 {
return native[2];
}
-(void)setV2:(float)v {
native[2] = v;
}
-(float)v3 {
return native[3];
}
-(void)setV3:(float)v {
native[3] = v;
}
-(instancetype)init {
return [self initWithV0:0.0 v1:0.0 v2:0.0 v3:0.0];
}
-(instancetype)initWithV0:(float)v0 v1:(float)v1 v2:(float)v2 v3:(float)v3 {
self = [super init];
if (self) {
self.v0 = v0;
self.v1 = v1;
self.v2 = v2;
self.v3 = v3;
}
return self;
}
-(instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
self = [super init];
if (self) {
[self set:vals];
}
return self;
}
+(instancetype)fromNative:(cv::Vec4f&)vec4f {
return [[Float4 alloc] initWithV0:vec4f[0] v1:vec4f[1] v2:vec4f[2] v3:vec4f[3]];
}
-(void)set:(NSArray<NSNumber*>*)vals {
self.v0 = (vals != nil && vals.count > 0) ? vals[0].floatValue : 0;
self.v1 = (vals != nil && vals.count > 1) ? vals[1].floatValue : 0;
self.v2 = (vals != nil && vals.count > 2) ? vals[2].floatValue : 0;
self.v3 = (vals != nil && vals.count > 3) ? vals[3].floatValue : 0;
}
-(NSArray<NSNumber*>*)get {
return @[[NSNumber numberWithFloat:native[0]], [NSNumber numberWithFloat:native[1]], [NSNumber numberWithFloat:native[2]], [NSNumber numberWithFloat:native[3]]];
}
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
} else if (![other isKindOfClass:[Float4 class]]) {
return NO;
} else {
Float4* point = (Float4*)other;
return self.v0 == point.v0 && self.v1 == point.v1 && self.v2 == point.v2 && self.v3 == point.v3;
}
}
@end

View File

@ -0,0 +1,114 @@
//
// Float6.h
//
// Created by Giles Payne on 2020/02/05.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
#import <Foundation/Foundation.h>
@class Mat;
NS_ASSUME_NONNULL_BEGIN
/**
* Simple wrapper for a vector of six `float`
*/
CV_EXPORTS @interface Float6 : NSObject
#pragma mark - Properties
/**
* First vector element
*/
@property float v0;
/**
* Second vector element
*/
@property float v1;
/**
* Third vector element
*/
@property float v2;
/**
* Fourth vector element
*/
@property float v3;
/**
* Fifth vector element
*/
@property float v4;
/**
* Sixth vector element
*/
@property float v5;
#ifdef __cplusplus
/**
* The wrapped vector
*/
@property(readonly) cv::Vec6f& nativeRef;
#endif
#pragma mark - Constructors
/**
* Create zero-initialize vecior
*/
-(instancetype)init;
/**
* Create vector with specified element values
* @param v0 First element
* @param v1 Second element
* @param v2 Third element
* @param v3 Fourth element
* @param v4 Fifth element
* @param v5 Sixth element
*/
-(instancetype)initWithV0:(float)v0 v1:(float)v1 v2:(float)v2 v3:(float)v3 v4:(float)v4 v5:(float)v5;
/**
* Create vector with specified element values
* @param vals array of element values
*/
-(instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#ifdef __cplusplus
+(instancetype)fromNative:(cv::Vec6f&)vec6f;
#endif
/**
* Update vector with specified element values
* @param vals array of element values
*/
-(void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
/**
* Get vector as an array
*/
-(NSArray<NSNumber*>*)get;
#pragma mark - Common Methods
/**
* Compare for equality
* @param other Object to compare
*/
-(BOOL)isEqual:(nullable id)other;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,115 @@
//
// Float6.mm
//
// Created by Giles Payne on 2020/02/05.
//
#import "Float6.h"
#import "Mat.h"
@implementation Float6 {
cv::Vec6f native;
}
-(float)v0 {
return native[0];
}
-(void)setV0:(float)v {
native[0] = v;
}
-(float)v1 {
return native[1];
}
-(void)setV1:(float)v {
native[1] = v;
}
-(float)v2 {
return native[2];
}
-(void)setV2:(float)v {
native[2] = v;
}
-(float)v3 {
return native[3];
}
-(void)setV3:(float)v {
native[3] = v;
}
-(float)v4 {
return native[4];
}
-(void)setV4:(float)v {
native[4] = v;
}
-(float)v5 {
return native[5];
}
-(void)setV5:(float)v {
native[5] = v;
}
-(instancetype)init {
return [self initWithV0:0.0 v1:0.0 v2:0.0 v3:0.0 v4:0.0 v5:0.0];
}
-(instancetype)initWithV0:(float)v0 v1:(float)v1 v2:(float)v2 v3:(float)v3 v4:(float)v4 v5:(float)v5 {
self = [super init];
if (self) {
self.v0 = v0;
self.v1 = v1;
self.v2 = v2;
self.v3 = v3;
self.v4 = v4;
self.v5 = v5;
}
return self;
}
-(instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
self = [super init];
if (self) {
[self set:vals];
}
return self;
}
+(instancetype)fromNative:(cv::Vec6f&)vec6f {
return [[Float6 alloc] initWithV0:vec6f[0] v1:vec6f[1] v2:vec6f[2] v3:vec6f[3] v4:vec6f[4] v5:vec6f[5]];
}
-(void)set:(NSArray<NSNumber*>*)vals {
self.v0 = (vals != nil && vals.count > 0) ? vals[0].floatValue : 0.0;
self.v1 = (vals != nil && vals.count > 1) ? vals[1].floatValue : 0.0;
self.v2 = (vals != nil && vals.count > 2) ? vals[2].floatValue : 0.0;
self.v3 = (vals != nil && vals.count > 3) ? vals[3].floatValue : 0.0;
self.v4 = (vals != nil && vals.count > 4) ? vals[4].floatValue : 0.0;
self.v5 = (vals != nil && vals.count > 5) ? vals[5].floatValue : 0.0;
}
-(NSArray<NSNumber*>*)get {
return @[[NSNumber numberWithFloat:native[0]], [NSNumber numberWithFloat:native[1]], [NSNumber numberWithFloat:native[2]], [NSNumber numberWithFloat:native[3]], [NSNumber numberWithFloat:native[4]], [NSNumber numberWithFloat:native[5]]];
}
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
} else if (![other isKindOfClass:[Float6 class]]) {
return NO;
} else {
Float6* point = (Float6*)other;
return self.v0 == point.v0 && self.v1 == point.v1 && self.v2 == point.v2 && self.v3 == point.v3 && self.v4 == point.v4 && self.v5 == point.v5;
}
}
@end

View File

@ -0,0 +1,89 @@
//
// FloatVector.h
//
// Created by Giles Payne on 2020/01/04.
//
#pragma once
#import <Foundation/Foundation.h>
#ifdef __cplusplus
#import <vector>
#endif
#import "CVObjcUtil.h"
NS_ASSUME_NONNULL_BEGIN
/**
* Utility class to wrap a `std::vector<float>`
*/
CV_EXPORTS @interface FloatVector : NSObject
#pragma mark - Constructors
/**
* Create FloatVector and initialize with the contents of an NSData object
* @param data NSData containing raw float array
*/
-(instancetype)initWithData:(NSData*)data;
/**
* Create FloatVector and initialize with the contents of another FloatVector object
* @param src FloatVector containing data to copy
*/
-(instancetype)initWithVector:(FloatVector*)src;
#ifdef __OBJC__
/**
* Create FloatVector from raw C array
* @param array The raw C array
* @elements elements The number of elements in the array
*/
-(instancetype)initWithNativeArray:(float*)array elements:(NSInteger)elements;
#endif
#ifdef __cplusplus
/**
* Create FloatVector from std::vector<float>
* @param src The std::vector<float> object to wrap
*/
-(instancetype)initWithStdVector:(std::vector<float>&)src;
+(instancetype)fromNative:(std::vector<float>&)src;
#endif
#pragma mark - Properties
/**
* Length of the vector
*/
@property(readonly) NSInteger length;
#ifdef __OBJC__
/**
* Raw C array
*/
@property(readonly) float* nativeArray;
#endif
#ifdef __cplusplus
/**
* The wrapped std::vector<float> object
*/
@property(readonly) std::vector<float>& nativeRef;
#endif
/**
* NSData object containing the raw float data
*/
@property(readonly) NSData* data;
#pragma mark - Accessor method
/**
* Return array element
* @param index Index of the array element to return
*/
-(float)get:(NSInteger)index;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,76 @@
//
// FloatVector.m
//
// Created by Giles Payne on 2020/01/04.
//
#import "FloatVector.h"
#import <vector>
@implementation FloatVector {
std::vector<float> v;
}
-(instancetype)initWithData:(NSData*)data {
self = [super init];
if (self) {
if (data.length % sizeof(float) != 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Invalid data length" userInfo:nil];
}
v.insert(v.begin(), (float*)data.bytes, (float*)data.bytes + data.length/sizeof(float));
}
return self;
}
-(instancetype)initWithVector:(FloatVector *)src {
self = [super init];
if (self) {
v.insert(v.begin(), src.nativeRef.begin(), src.nativeRef.end());
}
return self;
}
-(NSInteger)length {
return v.size();
}
-(float*)nativeArray {
return (float*)v.data();
}
-(instancetype)initWithNativeArray:(float*)array elements:(NSInteger)elements {
self = [super init];
if (self) {
v.insert(v.begin(), array, array + elements);
}
return self;
}
- (std::vector<float>&)nativeRef {
return v;
}
-(instancetype)initWithStdVector:(std::vector<float>&)src {
self = [super init];
if (self) {
v.insert(v.begin(), src.begin(), src.end());
}
return self;
}
+(instancetype)fromNative:(std::vector<float>&)src {
return [[FloatVector alloc] initWithStdVector:src];
}
-(float)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(float)) freeWhenDone:NO];
}
@end

View File

@ -0,0 +1,53 @@
//
// FloatVectorExt.swift
//
// Created by Giles Payne on 2020/01/04.
//
import Foundation
public extension FloatVector {
convenience init(_ array:[Float]) {
let data = array.withUnsafeBufferPointer { Data(buffer: $0) }
self.init(data:data);
}
subscript(index: Int) -> Float {
get {
return self.get(index)
}
}
var array: [Float] {
get {
var ret = Array<Float>(repeating: 0, count: data.count/MemoryLayout<Float>.stride)
_ = ret.withUnsafeMutableBytes { data.copyBytes(to: $0) }
return ret
}
}
}
extension FloatVector : Sequence {
public typealias Iterator = FloatVectorIterator
public func makeIterator() -> FloatVectorIterator {
return FloatVectorIterator(self)
}
}
public struct FloatVectorIterator: IteratorProtocol {
public typealias Element = Float
let floatVector: FloatVector
var pos = 0
init(_ floatVector: FloatVector) {
self.floatVector = floatVector
}
mutating public func next() -> Float? {
guard pos >= 0 && pos < floatVector.length
else { return nil }
pos += 1
return floatVector.get(pos - 1)
}
}

View File

@ -0,0 +1,101 @@
//
// Int4.h
//
// Created by Giles Payne on 2020/02/05.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
#import <Foundation/Foundation.h>
@class Mat;
NS_ASSUME_NONNULL_BEGIN
/**
* Simple wrapper for a vector of four `int`
*/
CV_EXPORTS @interface Int4 : NSObject
#pragma mark - Properties
/**
* First vector element
*/
@property int v0;
/**
* Second vector element
*/
@property int v1;
/**
* Third vector element
*/
@property int v2;
/**
* Fourth vector element
*/
@property int v3;
#ifdef __cplusplus
/**
* The wrapped vector
*/
@property(readonly) cv::Vec4i& nativeRef;
#endif
#pragma mark - Constructors
/**
* Create zero-initialize vecior
*/
-(instancetype)init;
/**
* Create vector with specified element values
* @param v0 First element
* @param v1 Second element
* @param v2 Third element
* @param v3 Fourth element
*/
-(instancetype)initWithV0:(int)v0 v1:(int)v1 v2:(int)v2 v3:(int)v3;
/**
* Create vector with specified element values
* @param vals array of element values
*/
-(instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#ifdef __cplusplus
+(instancetype)fromNative:(cv::Vec4i&)vec4i;
#endif
/**
* Update vector with specified element values
* @param vals array of element values
*/
-(void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
/**
* Get vector as an array
*/
-(NSArray<NSNumber*>*)get;
#pragma mark - Common Methods
/**
* Compare for equality
* @param other Object to compare
*/
-(BOOL)isEqual:(nullable id)other;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,95 @@
//
// Int4.mm
//
// Created by Giles Payne on 2020/02/05.
//
#import "Int4.h"
#import "Mat.h"
@implementation Int4 {
cv::Vec4i native;
}
-(int)v0 {
return native[0];
}
-(void)setV0:(int)v {
native[0] = v;
}
-(int)v1 {
return native[1];
}
-(void)setV1:(int)v {
native[1] = v;
}
-(int)v2 {
return native[2];
}
-(void)setV2:(int)v {
native[2] = v;
}
-(int)v3 {
return native[3];
}
-(void)setV3:(int)v {
native[3] = v;
}
-(instancetype)init {
return [self initWithV0:0 v1:0 v2:0 v3:0];
}
-(instancetype)initWithV0:(int)v0 v1:(int)v1 v2:(int)v2 v3:(int)v3 {
self = [super init];
if (self) {
self.v0 = v0;
self.v1 = v1;
self.v2 = v2;
self.v3 = v3;
}
return self;
}
-(instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
self = [super init];
if (self) {
[self set:vals];
}
return self;
}
+(instancetype)fromNative:(cv::Vec4i&)vec4i {
return [[Int4 alloc] initWithV0:vec4i[0] v1:vec4i[1] v2:vec4i[2] v3:vec4i[3]];
}
-(void)set:(NSArray<NSNumber*>*)vals {
self.v0 = (vals != nil && vals.count > 0) ? vals[0].intValue : 0;
self.v1 = (vals != nil && vals.count > 1) ? vals[1].intValue : 0;
self.v2 = (vals != nil && vals.count > 2) ? vals[2].intValue : 0;
self.v3 = (vals != nil && vals.count > 3) ? vals[3].intValue : 0;
}
-(NSArray<NSNumber*>*)get {
return @[[NSNumber numberWithFloat:native[0]], [NSNumber numberWithFloat:native[1]], [NSNumber numberWithFloat:native[2]], [NSNumber numberWithFloat:native[3]]];
}
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
} else if (![other isKindOfClass:[Int4 class]]) {
return NO;
} else {
Int4* point = (Int4*)other;
return self.v0 == point.v0 && self.v1 == point.v1 && self.v2 == point.v2 && self.v3 == point.v3;
}
}
@end

View File

@ -0,0 +1,89 @@
//
// IntVector.h
//
// Created by Giles Payne on 2020/01/04.
//
#pragma once
#import <Foundation/Foundation.h>
#ifdef __cplusplus
#import <vector>
#endif
#import "CVObjcUtil.h"
NS_ASSUME_NONNULL_BEGIN
/**
* Utility class to wrap a `std::vector<int>`
*/
CV_EXPORTS @interface IntVector : NSObject
#pragma mark - Constructors
/**
* Create IntVector and initialize with the contents of an NSData object
* @param data NSData containing raw int array
*/
-(instancetype)initWithData:(NSData*)data;
/**
* Create IntVector and initialize with the contents of another IntVector object
* @param src IntVector containing data to copy
*/
-(instancetype)initWithVector:(IntVector*)src;
#ifdef __OBJC__
/**
* Create IntVector from raw C array
* @param array The raw C array
* @elements elements The number of elements in the array
*/
-(instancetype)initWithNativeArray:(int*)array elements:(NSInteger)elements;
#endif
#ifdef __cplusplus
/**
* Create IntVector from std::vector<int>
* @param src The std::vector<int> object to wrap
*/
-(instancetype)initWithStdVector:(std::vector<int>&)src;
+(instancetype)fromNative:(std::vector<int>&)src;
#endif
#pragma mark - Properties
/**
* Length of the vector
*/
@property(readonly) NSInteger length;
#ifdef __OBJC__
/**
* Raw C array
*/
@property(readonly) int* nativeArray;
#endif
#ifdef __cplusplus
/**
* The wrapped std::vector<int> object
*/
@property(readonly) std::vector<int>& nativeRef;
#endif
/**
* NSData object containing the raw int data
*/
@property(readonly) NSData* data;
#pragma mark - Accessor method
/**
* Return array element
* @param index Index of the array element to return
*/
-(int)get:(NSInteger)index;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,76 @@
//
// IntVector.m
//
// Created by Giles Payne on 2020/01/04.
//
#import "IntVector.h"
#import <vector>
@implementation IntVector {
std::vector<int> v;
}
-(instancetype)initWithData:(NSData*)data {
self = [super init];
if (self) {
if (data.length % sizeof(int) != 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Invalid data length" userInfo:nil];
}
v.insert(v.begin(), (int*)data.bytes, (int*)data.bytes + data.length/sizeof(int));
}
return self;
}
-(instancetype)initWithVector:(IntVector*)src {
self = [super init];
if (self) {
v.insert(v.begin(), src.nativeRef.begin(), src.nativeRef.end());
}
return self;
}
-(NSInteger)length {
return v.size();
}
-(int*)nativeArray {
return (int*)v.data();
}
-(instancetype)initWithNativeArray:(int*)array elements:(NSInteger)elements {
self = [super init];
if (self) {
v.insert(v.begin(), array, array + elements);
}
return self;
}
- (std::vector<int>&)nativeRef {
return v;
}
-(instancetype)initWithStdVector:(std::vector<int>&)src {
self = [super init];
if (self) {
v.insert(v.begin(), src.begin(), src.end());
}
return self;
}
+(instancetype)fromNative:(std::vector<int>&)src {
return [[IntVector alloc] initWithStdVector:src];
}
-(int)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(int)) freeWhenDone:NO];
}
@end

View File

@ -0,0 +1,53 @@
//
// IntVectorExt.swift
//
// Created by Giles Payne on 2020/01/04.
//
import Foundation
public extension IntVector {
convenience init(_ array:[Int32]) {
let data = array.withUnsafeBufferPointer { Data(buffer: $0) }
self.init(data:data);
}
subscript(index: Int) -> Int32 {
get {
return self.get(index)
}
}
var array: [Int32] {
get {
var ret = Array<Int32>(repeating: 0, count: data.count/MemoryLayout<Int32>.stride)
_ = ret.withUnsafeMutableBytes { data.copyBytes(to: $0) }
return ret
}
}
}
extension IntVector : Sequence {
public typealias Iterator = IntVectorIterator
public func makeIterator() -> IntVectorIterator {
return IntVectorIterator(self)
}
}
public struct IntVectorIterator: IteratorProtocol {
public typealias Element = Int32
let intVector: IntVector
var pos = 0
init(_ intVector: IntVector) {
self.intVector = intVector
}
mutating public func next() -> Int32? {
guard pos >= 0 && pos < intVector.length
else { return nil }
pos += 1
return intVector.get(pos - 1)
}
}

View File

@ -0,0 +1,100 @@
//
// KeyPoint.h
//
// Created by Giles Payne on 2019/10/08.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
#import <Foundation/Foundation.h>
@class Point2f;
NS_ASSUME_NONNULL_BEGIN
/**
* Object representing a point feature found by one of many available keypoint detectors, such as Harris corner detector, FAST, StarDetector, SURF, SIFT etc.
*/
CV_EXPORTS @interface KeyPoint : NSObject
#pragma mark - Properties
/**
* Coordinates of the keypoint.
*/
@property Point2f* pt;
/**
* Diameter of the useful keypoint adjacent area.
*/
@property float size;
/**
* Computed orientation of the keypoint (-1 if not applicable).
*/
@property float angle;
/**
* The response, by which the strongest keypoints have been selected. Can
* be used for further sorting or subsampling.
*/
@property float response;
/**
* Octave (pyramid layer), from which the keypoint has been extracted.
*/
@property int octave;
/**
* Object ID, that can be used to cluster keypoints by an object they
* belong to.
*/
@property int classId;
#ifdef __cplusplus
@property(readonly) cv::KeyPoint& nativeRef;
#endif
#pragma mark - Constructors
- (instancetype)init;
- (instancetype)initWithX:(float)x y:(float)y size:(float)size angle:(float)angle response:(float)response octave:(int)octave classId:(int)classId;
- (instancetype)initWithX:(float)x y:(float)y size:(float)size angle:(float)angle response:(float)response octave:(int)octave;
- (instancetype)initWithX:(float)x y:(float)y size:(float)size angle:(float)angle response:(float)response;
- (instancetype)initWithX:(float)x y:(float)y size:(float)size angle:(float)angle;
- (instancetype)initWithX:(float)x y:(float)y size:(float)size;
#ifdef __cplusplus
+ (instancetype)fromNative:(cv::KeyPoint&)keyPoint;
#endif
#pragma mark - Common Methods
/**
* Clone object
*/
- (KeyPoint*)clone;
/**
* Compare for equality
* @param other Object to compare
*/
- (BOOL)isEqual:(nullable id)other;
/**
* Calculate hash value for this object
*/
- (NSUInteger)hash;
/**
* Returns a string that describes the contents of the object
*/
- (NSString*)description;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,96 @@
//
// KeyPoint.m
//
// Created by Giles Payne on 2019/12/25.
//
#import "KeyPoint.h"
#import "Point2f.h"
@implementation KeyPoint {
cv::KeyPoint native;
}
- (cv::KeyPoint&)nativeRef {
native.pt.x = self.pt.x;
native.pt.y = self.pt.y;
native.size = self.size;
native.angle = self.angle;
native.response = self.response;
native.octave = self.octave;
native.class_id = self.classId;
return native;
}
- (instancetype)init {
return [self initWithX:0 y:0 size:0];
}
- (instancetype)initWithX:(float)x y:(float)y size:(float)size angle:(float)angle response:(float)response octave:(int)octave classId:(int)classId {
self = [super init];
if (self != nil) {
self.pt = [[Point2f alloc] initWithX:x y:y];
self.size = size;
self.angle = angle;
self.response = response;
self.octave = octave;
self.classId = classId;
}
return self;
}
- (instancetype)initWithX:(float)x y:(float)y size:(float)size angle:(float)angle response:(float)response octave:(int)octave {
return [self initWithX:x y:y size:size angle:angle response:response octave:octave classId:-1];
}
- (instancetype)initWithX:(float)x y:(float)y size:(float)size angle:(float)angle response:(float)response {
return [self initWithX:x y:y size:size angle:angle response:response octave:0];
}
- (instancetype)initWithX:(float)x y:(float)y size:(float)size angle:(float)angle {
return [self initWithX:x y:y size:size angle:angle response:0];
}
- (instancetype)initWithX:(float)x y:(float)y size:(float)size {
return [self initWithX:x y:y size:size angle:-1];
}
+ (instancetype)fromNative:(cv::KeyPoint&)keyPoint {
return [[KeyPoint alloc] initWithX:keyPoint.pt.x y:keyPoint.pt.y size:keyPoint.size angle:keyPoint.angle response:keyPoint.response octave:keyPoint.octave classId:keyPoint.class_id];
}
- (KeyPoint*)clone {
return [[KeyPoint alloc] initWithX:self.pt.x y:self.pt.y size:self.size angle:self.angle response:self.response octave:self.octave classId:self.classId];
}
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
} else if (![other isKindOfClass:[KeyPoint class]]) {
return NO;
} else {
KeyPoint* keyPoint = (KeyPoint*)other;
return [self.pt isEqual:keyPoint.pt] && self.size == keyPoint.size && self.angle == keyPoint.angle && self.response == keyPoint.response && self.octave == keyPoint.octave && self.classId == keyPoint.classId;
}
}
#define FLOAT_TO_BITS(x) ((Cv32suf){ .f = x }).i
- (NSUInteger)hash {
int prime = 31;
uint32_t result = 1;
result = prime * result + FLOAT_TO_BITS(self.pt.x);
result = prime * result + FLOAT_TO_BITS(self.pt.y);
result = prime * result + FLOAT_TO_BITS(self.size);
result = prime * result + FLOAT_TO_BITS(self.angle);
result = prime * result + FLOAT_TO_BITS(self.response);
result = prime * result + self.octave;
result = prime * result + self.classId;
return result;
}
- (NSString*)description {
return [NSString stringWithFormat:@"KeyPoint { pt: %@, size: %f, angle: %f, response: %f, octave: %d, classId: %d}", self.pt.description, self.size, self.angle, self.response, self.octave, self.classId];
}
@end

View File

@ -0,0 +1,187 @@
//
// Mat.h
//
// Created by Giles Payne on 2019/10/06.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
#import <Foundation/Foundation.h>
@class Size2i;
@class Scalar;
@class Range;
@class Rect2i;
@class Point2i;
NS_ASSUME_NONNULL_BEGIN
/**
The class Mat represents an n-dimensional dense numerical single-channel or multi-channel array.
####Swift Example
```swift
let mat = Mat(rows: 2, cols: 3, type: CvType.CV_8U)
try! mat.put(row: 0, col: 0, data: [2, 3, 4, 4, 5, 6] as [Int8])
print("mat: \(mat.dump())")
```
####Objective-C Example
```objc
Mat* mat = [[Mat alloc] initWithRows:2 cols:3 type: CV_8U];
[m1 put:0 col:0 data:@[@2, @3, @4, @3, @4, @5]];
NSLog(@"mat: %@", [m1 dump]);
```
*/
CV_EXPORTS @interface Mat : NSObject
#ifdef __cplusplus
@property(readonly) cv::Ptr<cv::Mat> nativePtr;
@property(readonly) cv::Mat& nativeRef;
#endif
#pragma mark - Constructors
- (instancetype)init;
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Ptr<cv::Mat>)nativeMat;
+ (instancetype)fromNativePtr:(cv::Ptr<cv::Mat>)nativePtr;
+ (instancetype)fromNative:(cv::Mat&)nativeRef;
#endif
/**
Creates a Mat object with the specified number of rows and columns and Mat type
@param rows Number of rows
@param cols Number of columns
@param type Mat type (refer: `CvType`)
*/
- (instancetype)initWithRows:(int)rows cols:(int)cols type:(int)type;
- (instancetype)initWithRows:(int)rows cols:(int)cols type:(int)type data:(NSData*)data;
- (instancetype)initWithRows:(int)rows cols:(int)cols type:(int)type data:(NSData*)data step:(long)step;
- (instancetype)initWithSize:(Size2i*)size type:(int)type;
- (instancetype)initWithSizes:(NSArray<NSNumber*>*)sizes type:(int)type;
- (instancetype)initWithRows:(int)rows cols:(int)cols type:(int)type scalar:(Scalar*)scalar;
- (instancetype)initWithSize:(Size2i*)size type:(int)type scalar:(Scalar*)scalar;
- (instancetype)initWithSizes:(NSArray<NSNumber*>*)sizes type:(int)type scalar:(Scalar*)scalar;
- (instancetype)initWithMat:(Mat*)mat rowRange:(Range*)rowRange colRange:(Range*)colRange;
- (instancetype)initWithMat:(Mat*)mat rowRange:(Range*)rowRange;
- (instancetype)initWithMat:(Mat*)mat ranges:(NSArray<Range*>*)ranges;
- (instancetype)initWithMat:(Mat*)mat rect:(Rect2i*)roi;
#pragma mark - Mat operations
- (Mat*)adjustRoiTop:(int)dtop bottom:(int)dbottom left:(int)dleft right:(int)dright NS_SWIFT_NAME(adjustRoi(top:bottom:left:right:));
- (void)assignTo:(Mat*)mat type:(int)type;
- (void)assignTo:(Mat*)mat;
- (BOOL)isSameMat:(Mat*)mat;
- (int)channels;
- (int)checkVector:(int)elemChannels depth:(int)depth requireContinuous:(BOOL) requireContinuous NS_SWIFT_NAME(checkVector(elemChannels:depth:requireContinuous:));
- (int)checkVector:(int)elemChannels depth:(int)depth NS_SWIFT_NAME(checkVector(elemChannels:depth:));
- (int)checkVector:(int)elemChannels NS_SWIFT_NAME(checkVector(elemChannels:));
- (Mat*)clone;
- (Mat*)col:(int)x;
- (Mat*)colRange:(int)start end:(int)end NS_SWIFT_NAME(colRange(start:end:));
- (Mat*)colRange:(Range*)range;
- (int)dims;
- (int)cols;
- (void)convertTo:(Mat*)mat rtype:(int)rtype alpha:(double)alpha beta:(double)beta;
- (void)convertTo:(Mat*)mat rtype:(int)rtype alpha:(double)alpha;
- (void)convertTo:(Mat*)mat rtype:(int)rtype;
- (void)copyTo:(Mat*)mat;
- (void)copyTo:(Mat*)mat mask:(Mat*)mask;
- (void)create:(int)rows cols:(int)cols type:(int)type NS_SWIFT_NAME(create(rows:cols:type:));
- (void)create:(Size2i*)size type:(int)type NS_SWIFT_NAME(create(size:type:));
- (void)createEx:(NSArray<NSNumber*>*)sizes type:(int)type NS_SWIFT_NAME(create(sizes:type:));
- (void)copySize:(Mat*)mat;
- (Mat*)cross:(Mat*)mat;
- (unsigned char*)dataPtr NS_SWIFT_NAME(dataPointer());
- (int)depth;
- (Mat*)diag:(int)diagonal;
- (Mat*)diag;
+ (Mat*)diag:(Mat*)diagonal;
- (double)dot:(Mat*)mat;
- (long)elemSize;
- (long)elemSize1;
- (BOOL)empty;
+ (Mat*)eye:(int)rows cols:(int)cols type:(int)type NS_SWIFT_NAME(eye(rows:cols:type:));
+ (Mat*)eye:(Size2i*)size type:(int)type NS_SWIFT_NAME(eye(size:type:));
- (Mat*)inv:(int)method;
- (Mat*)inv;
- (BOOL)isContinuous;
- (BOOL)isSubmatrix;
- (void)locateROI:(Size2i*)wholeSize ofs:(Point2i*)offset NS_SWIFT_NAME(locateROI(wholeSize:offset:));
- (Mat*)mul:(Mat*)mat scale:(double)scale;
/**
Performs element-wise multiplication
@param mat operand with with which to perform element-wise multiplication
*/
- (Mat*)mul:(Mat*)mat;
/**
Performs matrix multiplication
@param mat operand with with which to perform matrix multiplication
@see `Core.gemm(...)`
*/
- (Mat*)matMul:(Mat*)mat;
+ (Mat*)ones:(int)rows cols:(int)cols type:(int)type NS_SWIFT_NAME(ones(rows:cols:type:));
+ (Mat*)ones:(Size2i*)size type:(int)type NS_SWIFT_NAME(ones(size:type:));
+ (Mat*)onesEx:(NSArray<NSNumber*>*)sizes type:(int)type NS_SWIFT_NAME(ones(sizes:type:));
- (void)push_back:(Mat*)mat;
- (Mat*)reshape:(int)channels rows:(int)rows NS_SWIFT_NAME(reshape(channels:rows:));
- (Mat*)reshape:(int)channels NS_SWIFT_NAME(reshape(channels:));
- (Mat*)reshape:(int)channels newshape:(NSArray<NSNumber*>*)newshape NS_SWIFT_NAME(reshape(channels:newshape:));
- (Mat*)row:(int)y;
- (Mat*)rowRange:(int)start end:(int)end NS_SWIFT_NAME(rowRange(start:end:));
- (Mat*)rowRange:(Range*)range;
- (int)rows;
- (Mat*)setToScalar:(Scalar*)scalar NS_SWIFT_NAME(setTo(scalar:));
- (Mat*)setToScalar:(Scalar*)scalar mask:(Mat*)mask NS_SWIFT_NAME(setTo(scalar:mask:));
- (Mat*)setToValue:(Mat*)value mask:(Mat*)mask NS_SWIFT_NAME(setTo(value:mask:));
- (Mat*)setToValue:(Mat*)value NS_SWIFT_NAME(setTo(value:));
- (Size2i*)size;
- (int)size:(int)dim;
- (long)step1:(int)dim;
- (long)step1;
- (Mat*)submat:(int)rowStart rowEnd:(int)rowEnd colStart:(int)colStart colEnd:(int)colEnd NS_SWIFT_NAME(submat(rowStart:rowEnd:colStart:colEnd:));
- (Mat*)submat:(Range*)rowRange colRange:(Range*)colRange NS_SWIFT_NAME(submat(rowRange:colRange:));
- (Mat*)submat:(NSArray<Range*>*)ranges NS_SWIFT_NAME(submat(ranges:));
- (Mat*)submatRoi:(Rect2i*)roi NS_SWIFT_NAME(submat(roi:));
- (Mat*)t;
- (long)total;
- (int)type;
+ (Mat*)zeros:(int)rows cols:(int)cols type:(int)type;
+ (Mat*)zeros:(Size2i*)size type:(int)type;
+ (Mat*)zerosEx:(NSArray<NSNumber*>*)sizes type:(int)type NS_SWIFT_NAME(zeros(sizes:type:));
- (NSString*)description;
- (NSString*)dump;
- (int)height;
- (int)width;
#pragma mark - Accessors
- (int)put:(int)row col:(int)col data:(NSArray<NSNumber*>*)data NS_REFINED_FOR_SWIFT;
- (int)put:(NSArray<NSNumber*>*)indices data:(NSArray<NSNumber*>*)data NS_REFINED_FOR_SWIFT;
- (int)get:(int)row col:(int)col data:(NSMutableArray<NSNumber*>*)data NS_REFINED_FOR_SWIFT;
- (int)get:(NSArray<NSNumber*>*)indices data:(NSMutableArray<NSNumber*>*)data NS_REFINED_FOR_SWIFT;
- (NSArray<NSNumber*>*)get:(int)row col:(int)col NS_REFINED_FOR_SWIFT;
- (NSArray<NSNumber*>*)get:(NSArray<NSNumber*>*)indices NS_REFINED_FOR_SWIFT;
- (int)get:(NSArray<NSNumber*>*)indices count:(int)count byteBuffer:(char*)buffer NS_REFINED_FOR_SWIFT;
- (int)get:(NSArray<NSNumber*>*)indices count:(int)count doubleBuffer:(double*)buffer NS_REFINED_FOR_SWIFT;
- (int)get:(NSArray<NSNumber*>*)indices count:(int)count floatBuffer:(float*)buffer NS_REFINED_FOR_SWIFT;
- (int)get:(NSArray<NSNumber*>*)indices count:(int)count intBuffer:(int*)buffer NS_REFINED_FOR_SWIFT;
- (int)get:(NSArray<NSNumber*>*)indices count:(int)count shortBuffer:(short*)buffer NS_REFINED_FOR_SWIFT;
- (int)put:(NSArray<NSNumber*>*)indices count:(int)count byteBuffer:(const char*)buffer NS_REFINED_FOR_SWIFT;
- (int)put:(NSArray<NSNumber*>*)indices count:(int)count doubleBuffer:(const double*)buffer NS_REFINED_FOR_SWIFT;
- (int)put:(NSArray<NSNumber*>*)indices count:(int)count floatBuffer:(const float*)buffer NS_REFINED_FOR_SWIFT;
- (int)put:(NSArray<NSNumber*>*)indices count:(int)count intBuffer:(const int*)buffer NS_REFINED_FOR_SWIFT;
- (int)put:(NSArray<NSNumber*>*)indices count:(int)count shortBuffer:(const short*)buffer NS_REFINED_FOR_SWIFT;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,935 @@
//
// Mat.m
//
// Created by Giles Payne on 2019/10/06.
//
#import "Mat.h"
#import "Size2i.h"
#import "Scalar.h"
#import "Range.h"
#import "Rect2i.h"
#import "Point2i.h"
#import "CvType.h"
#import "CVObjcUtil.h"
static int idx2Offset(cv::Mat* mat, std::vector<int>& indices) {
int offset = indices[0];
for (int dim=1; dim < mat->dims; dim++) {
offset = offset*mat->size[dim] + indices[dim];
}
return offset;
}
static void offset2Idx(cv::Mat* mat, size_t offset, std::vector<int>& indices) {
for (int dim=mat->dims-1; dim>=0; dim--) {
indices[dim] = offset % mat->size[dim];
offset = (offset - indices[dim]) / mat->size[dim];
}
}
// returns true if final index was reached
static bool updateIdx(cv::Mat* mat, std::vector<int>& indices, size_t inc) {
size_t currentOffset = idx2Offset(mat, indices);
size_t newOffset = currentOffset + inc;
bool reachedEnd = newOffset>=(size_t)mat->total();
offset2Idx(mat, reachedEnd?0:newOffset, indices);
return reachedEnd;
}
@implementation Mat {
NSData* _nsdata;
}
- (cv::Mat&)nativeRef {
return *_nativePtr;
}
- (instancetype)init {
self = [super init];
if (self) {
_nativePtr = cv::Ptr<cv::Mat>(new cv::Mat());
}
return self;
}
- (instancetype)initWithNativeMat:(cv::Ptr<cv::Mat>)nativePtr {
self = [super init];
if (self) {
_nativePtr = nativePtr;
}
return self;
}
+ (instancetype)fromNativePtr:(cv::Ptr<cv::Mat>)nativePtr {
return [[Mat alloc] initWithNativeMat:nativePtr];
}
+ (instancetype)fromNative:(cv::Mat&)nativeRef {
return [[Mat alloc] initWithNativeMat:cv::Ptr<cv::Mat>(new cv::Mat(nativeRef))];
}
- (instancetype)initWithRows:(int)rows cols:(int)cols type:(int)type {
self = [super init];
if (self) {
_nativePtr = new cv::Mat(rows, cols, type);
}
return self;
}
- (instancetype)initWithRows:(int)rows cols:(int)cols type:(int)type data:(NSData*)data {
self = [super init];
if (self) {
_nativePtr = new cv::Mat(rows, cols, type, (void*)data.bytes);
_nsdata = data; // hold onto a reference otherwise this object might be deallocated
}
return self;
}
- (instancetype)initWithRows:(int)rows cols:(int)cols type:(int)type data:(NSData*)data step:(long)step {
self = [super init];
if (self) {
_nativePtr = new cv::Mat(rows, cols, type, (void*)data.bytes, step);
_nsdata = data; // hold onto a reference otherwise this object might be deallocated
}
return self;
}
- (instancetype)initWithSize:(Size2i*)size type:(int)type {
self = [super init];
if (self) {
_nativePtr = new cv::Mat(size.width, size.height, type);
}
return self;
}
- (instancetype)initWithSizes:(NSArray<NSNumber*>*)sizes type:(int)type {
self = [super init];
if (self) {
std::vector<int> vSizes;
for (NSNumber* size in sizes) {
vSizes.push_back(size.intValue);
}
_nativePtr = new cv::Mat((int)sizes.count, vSizes.data(), type);
}
return self;
}
- (instancetype)initWithRows:(int)rows cols:(int)cols type:(int)type scalar:(Scalar*)scalar {
self = [super init];
if (self) {
cv::Scalar scalerTemp(scalar.val[0].doubleValue, scalar.val[1].doubleValue, scalar.val[2].doubleValue, scalar.val[3].doubleValue);
_nativePtr = new cv::Mat(rows, cols, type, scalerTemp);
}
return self;
}
- (instancetype)initWithSize:(Size2i*)size type:(int)type scalar:(Scalar *)scalar {
self = [super init];
if (self) {
cv::Scalar scalerTemp(scalar.val[0].doubleValue, scalar.val[1].doubleValue, scalar.val[2].doubleValue, scalar.val[3].doubleValue);
_nativePtr = new cv::Mat(size.width, size.height, type, scalerTemp);
}
return self;
}
- (instancetype)initWithSizes:(NSArray<NSNumber*>*)sizes type:(int)type scalar:(Scalar *)scalar {
self = [super init];
if (self) {
cv::Scalar scalerTemp(scalar.val[0].doubleValue, scalar.val[1].doubleValue, scalar.val[2].doubleValue, scalar.val[3].doubleValue);
std::vector<int> vSizes;
for (NSNumber* size in sizes) {
vSizes.push_back(size.intValue);
}
_nativePtr = new cv::Mat((int)sizes.count, vSizes.data(), type, scalerTemp);
}
return self;
}
- (instancetype)initWithMat:(Mat*)mat rowRange:(Range*)rowRange colRange:(Range*)colRange {
self = [super init];
if (self) {
cv::Range rows(rowRange.start, rowRange.end);
cv::Range cols(colRange.start, colRange.end);
_nativePtr = new cv::Mat(*(cv::Mat*)mat.nativePtr, rows, cols);
}
return self;
}
- (instancetype)initWithMat:(Mat*)mat rowRange:(Range*)rowRange {
self = [super init];
if (self) {
cv::Range rows(rowRange.start, rowRange.end);
_nativePtr = new cv::Mat(*(cv::Mat*)mat.nativePtr, rows);
}
return self;
}
- (instancetype)initWithMat:(Mat*)mat ranges:(NSArray<Range*>*)ranges {
self = [super init];
if (self) {
std::vector<cv::Range> tempRanges;
for (Range* range in ranges) {
tempRanges.push_back(cv::Range(range.start, range.end));
}
_nativePtr = new cv::Mat(mat.nativePtr->operator()(tempRanges));
}
return self;
}
- (instancetype)initWithMat:(Mat*)mat rect:(Rect2i*)roi {
self = [super init];
if (self) {
cv::Range rows(roi.y, roi.y + roi.height);
cv::Range cols(roi.x, roi.x + roi.width);
_nativePtr = new cv::Mat(*(cv::Mat*)mat.nativePtr, rows, cols);
}
return self;
}
- (BOOL)isSameMat:(Mat*)mat {
return self.nativePtr == mat.nativePtr;
}
- (Mat*)adjustRoiTop:(int)dtop bottom:(int)dbottom left:(int)dleft right:(int)dright {
cv::Mat adjusted = _nativePtr->adjustROI(dtop, dbottom, dleft, dright);
return [[Mat alloc] initWithNativeMat:new cv::Mat(adjusted)];
}
- (void)assignTo:(Mat*)mat type:(int)type {
_nativePtr->assignTo(*(cv::Mat*)mat.nativePtr, type);
}
- (void)assignTo:(Mat*)mat {
_nativePtr->assignTo(*(cv::Mat*)mat.nativePtr);
}
- (int)channels {
return _nativePtr->channels();
}
- (int)checkVector:(int)elemChannels depth:(int)depth requireContinuous:(BOOL) requireContinuous {
return _nativePtr->checkVector(elemChannels, depth, requireContinuous);
}
- (int)checkVector:(int)elemChannels depth:(int)depth {
return _nativePtr->checkVector(elemChannels, depth);
}
- (int)checkVector:(int)elemChannels {
return _nativePtr->checkVector(elemChannels);
}
- (Mat*)clone {
return [[Mat alloc] initWithNativeMat:(new cv::Mat(_nativePtr->clone()))];
}
- (Mat*)col:(int)x {
return [[Mat alloc] initWithNativeMat:(new cv::Mat(_nativePtr->col(x)))];
}
- (Mat*)colRange:(int)start end:(int)end {
return [[Mat alloc] initWithNativeMat:(new cv::Mat(_nativePtr->colRange(start, end)))];
}
- (Mat*)colRange:(Range*)range {
return [[Mat alloc] initWithNativeMat:(new cv::Mat(_nativePtr->colRange(range.start, range.end)))];
}
- (int)dims {
return _nativePtr->dims;
}
- (int)cols {
return _nativePtr->cols;
}
- (void)convertTo:(Mat*)mat rtype:(int)rtype alpha:(double)alpha beta:(double)beta {
_nativePtr->convertTo(*(cv::Mat*)mat->_nativePtr, rtype, alpha, beta);
}
- (void)convertTo:(Mat*)mat rtype:(int)rtype alpha:(double)alpha {
_nativePtr->convertTo(*(cv::Mat*)mat->_nativePtr, rtype, alpha);
}
- (void)convertTo:(Mat*)mat rtype:(int)rtype {
_nativePtr->convertTo(*(cv::Mat*)mat->_nativePtr, rtype);
}
- (void)copyTo:(Mat*)mat {
_nativePtr->copyTo(*(cv::Mat*)mat->_nativePtr);
}
- (void)copyTo:(Mat*)mat mask:(Mat*)mask {
_nativePtr->copyTo(*(cv::Mat*)mat->_nativePtr, *(cv::Mat*)mask->_nativePtr);
}
- (void)create:(int)rows cols:(int)cols type:(int)type {
_nativePtr->create(rows, cols, type);
}
- (void)create:(Size2i*)size type:(int)type {
cv::Size tempSize(size.width, size.height);
_nativePtr->create(tempSize, type);
}
- (void)createEx:(NSArray<NSNumber*>*)sizes type:(int)type {
std::vector<int> tempSizes;
for (NSNumber* size in sizes) {
tempSizes.push_back(size.intValue);
}
_nativePtr->create((int)tempSizes.size(), tempSizes.data(), type);
}
- (void)copySize:(Mat*)mat {
_nativePtr->copySize(*(cv::Mat*)mat.nativePtr);
}
- (Mat*)cross:(Mat*)mat {
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->cross(*(cv::Mat*)mat.nativePtr))];
}
- (unsigned char*)dataPtr {
return _nativePtr->data;
}
- (int)depth {
return _nativePtr->depth();
}
- (Mat*)diag:(int)diagonal {
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->diag(diagonal))];
}
- (Mat*)diag {
return [self diag:0];
}
+ (Mat*)diag:(Mat*)diagonal {
return [[Mat alloc] initWithNativeMat:new cv::Mat(cv::Mat::diag(*(cv::Mat*)diagonal.nativePtr))];
}
- (double)dot:(Mat*)mat {
return _nativePtr->dot(*(cv::Mat*)mat.nativePtr);
}
- (long)elemSize {
return _nativePtr->elemSize();
}
- (long)elemSize1 {
return _nativePtr->elemSize1();
}
- (BOOL)empty {
return _nativePtr->empty();
}
+ (Mat*)eye:(int)rows cols:(int)cols type:(int)type {
return [[Mat alloc] initWithNativeMat:new cv::Mat(cv::Mat::eye(rows, cols, type))];
}
+ (Mat*)eye:(Size2i*)size type:(int)type {
cv::Size tempSize(size.width, size.height);
return [[Mat alloc] initWithNativeMat:new cv::Mat(cv::Mat::eye(tempSize, type))];
}
- (Mat*)inv:(int)method {
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->inv(method))];
}
- (Mat*)inv {
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->inv())];
}
- (BOOL)isContinuous {
return _nativePtr->isContinuous();
}
- (BOOL)isSubmatrix {
return _nativePtr->isSubmatrix();
}
- (void)locateROI:(Size2i*)wholeSize ofs:(Point2i*)ofs {
cv::Size tempWholeSize;
cv::Point tempOfs;
_nativePtr->locateROI(tempWholeSize, tempOfs);
if (wholeSize != nil) {
wholeSize.width = tempWholeSize.width;
wholeSize.height = tempWholeSize.height;
}
if (ofs != nil) {
ofs.x = tempOfs.x;
ofs.y = tempOfs.y;
}
}
- (Mat*)mul:(Mat*)mat scale:(double)scale {
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->mul(*(cv::Mat*)mat.nativePtr, scale))];
}
- (Mat*)mul:(Mat*)mat {
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->mul(*(cv::Mat*)mat.nativePtr))];
}
- (Mat*)matMul:(Mat*)mat {
cv::Mat temp = self.nativeRef * mat.nativeRef;
return [Mat fromNative:temp];
}
+ (Mat*)ones:(int)rows cols:(int)cols type:(int)type {
return [[Mat alloc] initWithNativeMat:new cv::Mat(cv::Mat::ones(rows, cols, type))];
}
+ (Mat*)ones:(Size2i*)size type:(int)type {
cv::Size tempSize(size.width, size.height);
return [[Mat alloc] initWithNativeMat:new cv::Mat(cv::Mat::ones(tempSize, type))];
}
+ (Mat*)onesEx:(NSArray<NSNumber*>*)sizes type:(int)type {
std::vector<int> tempSizes;
for (NSNumber* size in sizes) {
tempSizes.push_back(size.intValue);
}
return [[Mat alloc] initWithNativeMat:new cv::Mat(cv::Mat::ones((int)tempSizes.size(), tempSizes.data(), type))];
}
- (void)push_back:(Mat*)mat {
_nativePtr->push_back(*(cv::Mat*)mat.nativePtr);
}
- (Mat*)reshape:(int)channels rows:(int)rows {
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->reshape(channels, rows))];
}
- (Mat*)reshape:(int)channels {
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->reshape(channels))];
}
- (Mat*)reshape:(int)channels newshape:(NSArray<NSNumber*>*)newshape {
std::vector<int> tempNewshape;
for (NSNumber* size in newshape) {
tempNewshape.push_back(size.intValue);
}
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->reshape(channels, tempNewshape))];
}
- (Mat*)row:(int)y {
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->row(y))];
}
- (Mat*)rowRange:(int)start end:(int)end {
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->rowRange(start, end))];
}
- (Mat*)rowRange:(Range*)range {
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->rowRange(range.start, range.end))];
}
- (int)rows {
return _nativePtr->rows;
}
- (Mat*)setToScalar:(Scalar*)scalar {
cv::Scalar tempScalar(scalar.val[0].doubleValue, scalar.val[1].doubleValue, scalar.val[2].doubleValue, scalar.val[3].doubleValue);
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->operator=(tempScalar))];
}
- (Mat*)setToScalar:(Scalar*)scalar mask:(Mat*)mask {
cv::Scalar tempScalar(scalar.val[0].doubleValue, scalar.val[1].doubleValue, scalar.val[2].doubleValue, scalar.val[3].doubleValue);
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->setTo(tempScalar, *(cv::Mat*)mask.nativePtr))];
}
- (Mat*)setToValue:(Mat*)value mask:(Mat*)mask {
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->setTo(*(cv::Mat*)value.nativePtr, *(cv::Mat*)mask.nativePtr))];
}
- (Mat*)setToValue:(Mat*)value {
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->setTo(*(cv::Mat*)value.nativePtr))];
}
- (Size2i*)size {
return [[Size2i alloc] initWithWidth:_nativePtr->size().width height:_nativePtr->size().height];
}
- (int)size:(int)dimIndex {
return _nativePtr->size[dimIndex];
}
- (long)step1:(int)dimIndex {
return _nativePtr->step1(dimIndex);
}
- (long)step1 {
return _nativePtr->step1();
}
- (Mat*)submat:(int)rowStart rowEnd:(int)rowEnd colStart:(int)colStart colEnd:(int)colEnd {
Range* rowRange = [[Range alloc] initWithStart:rowStart end:rowEnd];
Range* colRange = [[Range alloc] initWithStart:colStart end:colEnd];
return [self submat:rowRange colRange:colRange];
}
- (Mat*)submat:(Range*)rowRange colRange:(Range*)colRange {
cv::Range tempRowRange(rowRange.start, rowRange.end);
cv::Range tempColRange(colRange.start, colRange.end);
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->operator()(tempRowRange, tempColRange))];
}
- (Mat*)submat:(NSArray<Range*>*)ranges {
std::vector<cv::Range> tempRanges;
for (Range* range in ranges) {
tempRanges.push_back(cv::Range(range.start, range.end));
}
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->operator()(tempRanges))];
}
- (Mat*)submatRoi:(Rect2i*)roi {
cv::Rect tempRoi(roi.x, roi.y, roi.width, roi.height);
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->operator()(tempRoi))];
}
- (Mat*)t {
return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->t())];
}
- (long)total {
return _nativePtr->total();
}
- (int)type {
return _nativePtr->type();
}
+ (Mat*)zeros:(int)rows cols:(int)cols type:(int)type {
return [[Mat alloc] initWithNativeMat:new cv::Mat(cv::Mat::zeros(rows, cols, type))];
}
+ (Mat*)zeros:(Size2i*)size type:(int)type {
cv::Size tempSize(size.width, size.height);
return [[Mat alloc] initWithNativeMat:new cv::Mat(cv::Mat::zeros(tempSize, type))];
}
+ (Mat*)zerosEx:(NSArray<NSNumber*>*)sizes type:(int)type {
std::vector<int> tempSizes;
for (NSNumber* size in sizes) {
tempSizes.push_back(size.intValue);
}
return [[Mat alloc] initWithNativeMat:new cv::Mat(cv::Mat::zeros((int)tempSizes.size(), tempSizes.data(), type))];
}
- (NSString*)dimsDescription {
if (_nativePtr->dims <= 0) {
return @"-1*-1*";
} else {
NSMutableString* ret = [NSMutableString string];
for (int index=0; index<_nativePtr->dims; index++) {
[ret appendFormat:@"%d*", _nativePtr->size[index]];
}
return ret;
}
}
- (NSString*)description {
NSString* dimDesc = [self dimsDescription];
return [NSString stringWithFormat:@"Mat [ %@%@, isCont=%s, isSubmat=%s, nativeObj=0x%p, dataAddr=0x%p ]", dimDesc, [CvType typeToString:_nativePtr->type()], _nativePtr->isContinuous()?"YES":"NO", _nativePtr->isSubmatrix()?"YES":"NO", (void*)_nativePtr, (void*)_nativePtr->data];
}
- (NSString*)dump {
NSMutableString* ret = [NSMutableString string];
cv::Ptr<cv::Formatted> formatted = cv::Formatter::get()->format(*_nativePtr);
for(const char* format = formatted->next(); format; format = formatted->next()) {
[ret appendFormat:@"%s", format];
}
return ret;
}
template<typename T> void putData(uchar* dataDest, int count, T (^readData)(int)) {
T* tDataDest = (T*)dataDest;
for (int index = 0; index < count; index++) {
tDataDest[index] = readData(index);
}
}
- (void)put:(uchar*)dest data:(NSArray<NSNumber*>*)data offset:(int)offset count:(int)count {
int depth = _nativePtr->depth();
if (depth == CV_8U) {
putData(dest, count, ^uchar (int index) { return cv::saturate_cast<uchar>(data[offset + index].doubleValue);} );
} else if (depth == CV_8S) {
putData(dest, count, ^schar (int index) { return cv::saturate_cast<schar>(data[offset + index].doubleValue);} );
} else if (depth == CV_16U) {
putData(dest, count, ^ushort (int index) { return cv::saturate_cast<ushort>(data[offset + index].doubleValue);} );
} else if (depth == CV_16S) {
putData(dest, count, ^short (int index) { return cv::saturate_cast<short>(data[offset + index].doubleValue);} );
} else if (depth == CV_32S) {
putData(dest, count, ^int32_t (int index) { return cv::saturate_cast<int32_t>(data[offset + index].doubleValue);} );
} else if (depth == CV_32F) {
putData(dest, count, ^float (int index) { return cv::saturate_cast<float>(data[offset + index].doubleValue);} );
} else if (depth == CV_64F) {
putData(dest, count, ^double (int index) { return data[offset + index].doubleValue;} );
}
}
- (int)put:(NSArray<NSNumber*>*)indices data:(NSArray<NSNumber*>*)data {
cv::Mat* mat = _nativePtr;
int type = mat->type();
int rawValueSize = (int)(mat->elemSize() / mat->channels());
if (data == nil || data.count % [CvType channels:type] != 0) {
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Provided data element number (%lu) should be multiple of the Mat channels count (%d)", (unsigned long)(data == nil ? 0 : data.count), [CvType channels:type]]
userInfo:nil];
@throw exception;
}
std::vector<int> tempIndices;
for (NSNumber* index in indices) {
tempIndices.push_back(index.intValue);
}
for (int index = 0; index < mat->dims; index++) {
if (mat->size[index]<=tempIndices[index]) {
return 0; // indexes out of range
}
}
int arrayAvailable = (int)data.count;
int matAvailable = getMatAvailable(mat, tempIndices);
int available = MIN(arrayAvailable, matAvailable);
int copyOffset = 0;
int copyCount = MIN((mat->size[mat->dims - 1] - tempIndices[mat->dims - 1]) * mat->channels(), available);
int result = (int)(available * rawValueSize);
while (available > 0) {
[self put:mat->ptr(tempIndices.data()) data:data offset:(int)copyOffset count:copyCount];
if (updateIdx(mat, tempIndices, copyCount / mat->channels())) {
break;
}
available -= copyCount;
copyOffset += copyCount;
copyCount = MIN(mat->size[mat->dims-1] * mat->channels(), available);
}
return result;
}
- (int)put:(int)row col:(int)col data:(NSArray<NSNumber*>*)data {
NSArray<NSNumber*>* indices = @[[NSNumber numberWithInt:row], [NSNumber numberWithInt:col]];
return [self put:indices data:data];
}
template<typename T> void getData(uchar* dataSource, int count, void (^writeData)(int,T)) {
T* tDataSource = (T*)dataSource;
for (int index = 0; index < count; index++) {
writeData(index, tDataSource[index]);
}
}
- (void)get:(uchar*)source data:(NSMutableArray<NSNumber*>*)data offset:(int)offset count:(int)count {
int depth = _nativePtr->depth();
if (depth == CV_8U) {
getData(source, count, ^void (int index, uchar value) { data[offset + index] = [[NSNumber alloc] initWithUnsignedChar:value]; } );
} else if (depth == CV_8S) {
getData(source, count, ^void (int index, char value) { data[offset + index] = [[NSNumber alloc] initWithChar:value]; } );
} else if (depth == CV_16U) {
getData(source, count, ^void (int index, ushort value) { data[offset + index] = [[NSNumber alloc] initWithUnsignedShort:value]; } );
} else if (depth == CV_16S) {
getData(source, count, ^void (int index, short value) { data[offset + index] = [[NSNumber alloc] initWithShort:value]; } );
} else if (depth == CV_32S) {
getData(source, count, ^void (int index, int32_t value) { data[offset + index] = [[NSNumber alloc] initWithInt:value]; } );
} else if (depth == CV_32F) {
getData(source, count, ^void (int index, float value) { data[offset + index] = [[NSNumber alloc] initWithFloat:value]; } );
} else if (depth == CV_64F) {
getData(source, count, ^void (int index, double value) { data[offset + index] = [[NSNumber alloc] initWithDouble:value]; } );
}
}
- (int)get:(NSArray<NSNumber*>*)indices data:(NSMutableArray<NSNumber*>*)data {
cv::Mat* mat = _nativePtr;
int type = mat->type();
if (data == nil || data.count % [CvType channels:type] != 0) {
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Provided data element number (%lu) should be multiple of the Mat channels count (%d)", (unsigned long)(data == nil ? 0 : data.count), [CvType channels:type]]
userInfo:nil];
@throw exception;
}
std::vector<int> tempIndices;
for (NSNumber* index in indices) {
tempIndices.push_back(index.intValue);
}
for (int index = 0; index < mat->dims; index++) {
if (mat->size[index]<=tempIndices[index]) {
return 0; // indexes out of range
}
}
int arrayAvailable = (int)data.count;
int copyOffset = 0;
int matAvailable = getMatAvailable(mat, tempIndices);
int available = MIN(arrayAvailable, matAvailable);
int copyCount = MIN((mat->size[mat->dims - 1] - tempIndices[mat->dims - 1]) * mat->channels(), available);
int result = (int)(available * mat->elemSize() / mat->channels());
while (available > 0) {
[self get:mat->ptr(tempIndices.data()) data:data offset:(int)copyOffset count:copyCount];
if (updateIdx(mat, tempIndices, copyCount / mat->channels())) {
break;
}
available -= copyCount;
copyOffset += copyCount;
copyCount = MIN(mat->size[mat->dims-1] * mat->channels(), available);
}
return result;
}
- (int)get:(int)row col:(int)col data:(NSMutableArray<NSNumber*>*)data {
NSArray<NSNumber*>* indices = @[[NSNumber numberWithInt:row], [NSNumber numberWithInt:col]];
return [self get:indices data:data];
}
- (NSArray<NSNumber*>*)get:(int)row col:(int)col {
NSMutableArray<NSNumber*>* result = [NSMutableArray new];
for (int index = 0; index<_nativePtr->channels(); index++) {
[result addObject:@0];
}
[self get:row col:col data:result];
return result;
}
- (NSArray<NSNumber*>*)get:(NSArray<NSNumber*>*)indices {
NSMutableArray<NSNumber*>* result = [NSMutableArray new];
for (int index = 0; index<_nativePtr->channels(); index++) {
[result addObject:@0];
}
[self get:indices data:result];
return result;
}
template<typename T> void getData(uchar* source, void (^writeData)(int,T), int dataOffset, int dataLength) {
T* tSource = (T*)source;
for (int index = 0; index < dataLength; index++) {
writeData(dataOffset+index, tSource[index]);
}
}
int getMatAvailable(cv::Mat* mat, std::vector<int>& indices) {
int blockSize = 1;
int unavailableCount = 0;
for (int index = mat->dims - 1; index >= 0; index--) {
unavailableCount += blockSize * indices[index];
blockSize *= mat->size[index];
}
return (int)(mat->channels() * (mat->total() - unavailableCount));
}
template<typename T> int getData(NSArray<NSNumber*>* indices, cv::Mat* mat, int count, T* tBuffer) {
std::vector<int> tempIndices;
for (NSNumber* index in indices) {
tempIndices.push_back(index.intValue);
}
for (int index = 0; index < mat->dims; index++) {
if (mat->size[index]<=tempIndices[index]) {
return 0; // indexes out of range
}
}
int arrayAvailable = count;
size_t countBytes = count * sizeof(T);
size_t remainingBytes = (size_t)(mat->total() - idx2Offset(mat, tempIndices))*mat->elemSize();
countBytes = (countBytes>remainingBytes)?remainingBytes:countBytes;
int result = (int)countBytes;
int matAvailable = getMatAvailable(mat, tempIndices);
int available = MIN(arrayAvailable, matAvailable);
if (mat->isContinuous()) {
memcpy(tBuffer, mat->ptr(tempIndices.data()), available * sizeof(T));
} else {
char* buff = (char*)tBuffer;
size_t blockSize = mat->size[mat->dims-1] * mat->elemSize();
size_t firstPartialBlockSize = (mat->size[mat->dims-1] - tempIndices[mat->dims-1]) * mat->step[mat->dims-1];
for (int dim=mat->dims-2; dim>=0 && blockSize == mat->step[dim]; dim--) {
blockSize *= mat->size[dim];
firstPartialBlockSize += (mat->size[dim] - (tempIndices[dim]+1)) * mat->step[dim];
}
size_t copyCount = (countBytes<firstPartialBlockSize)?countBytes:firstPartialBlockSize;
uchar* data = mat->ptr(tempIndices.data());
while(countBytes>0) {
memcpy(buff, data, copyCount);
updateIdx(mat, tempIndices, copyCount / mat->elemSize());
countBytes -= copyCount;
buff += copyCount;
copyCount = countBytes<blockSize?countBytes:blockSize;
data = mat->ptr(tempIndices.data());
}
}
return result;
}
- (int)get:(NSArray<NSNumber*>*)indices count:(int)count byteBuffer:(char*)buffer {
int depth = _nativePtr->depth();
if (depth != CV_8U && depth != CV_8S) {
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Invalid depth (%@). Valid depths for this call are CV_8U or CV_8S.", [CvType typeToString:depth]]
userInfo:nil];
@throw exception;
}
return getData(indices, _nativePtr, count, buffer);
}
- (int)get:(NSArray<NSNumber*>*)indices count:(int)count doubleBuffer:(double*)buffer {
int depth = _nativePtr->depth();
if (depth != CV_64F) {
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Invalid depth (%@). Valid depth for this call is CV_64F.", [CvType typeToString:depth]]
userInfo:nil];
@throw exception;
}
return getData(indices, _nativePtr, count, buffer);
}
- (int)get:(NSArray<NSNumber*>*)indices count:(int)count floatBuffer:(float*)buffer {
int depth = _nativePtr->depth();
if (depth != CV_32F) {
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Invalid depth (%@). Valid depth for this call is CV_32F.", [CvType typeToString:depth]]
userInfo:nil];
@throw exception;
}
return getData(indices, _nativePtr, count, buffer);
}
- (int)get:(NSArray<NSNumber*>*)indices count:(int)count intBuffer:(int*)buffer {
int depth = _nativePtr->depth();
if (depth != CV_32S) {
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Invalid depth (%@). Valid depth for this call is CV_32S.", [CvType typeToString:depth]]
userInfo:nil];
@throw exception;
}
return getData(indices, _nativePtr, count, buffer);
}
- (int)get:(NSArray<NSNumber*>*)indices count:(int)count shortBuffer:(short*)buffer {
int depth = _nativePtr->depth();
if (depth != CV_16S && depth != CV_16U) {
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Invalid depth (%@). Valid depths for this call are CV_16S and CV_16U.", [CvType typeToString:depth]]
userInfo:nil];
@throw exception;
}
return getData(indices, _nativePtr, count, buffer);
}
template<typename T> int putData(NSArray<NSNumber*>* indices, cv::Mat* mat, int count, const T* tBuffer) {
std::vector<int> tempIndices;
for (NSNumber* index in indices) {
tempIndices.push_back(index.intValue);
}
for (int index = 0; index < mat->dims; index++) {
if (mat->size[index]<=tempIndices[index]) {
return 0; // indexes out of range
}
}
int arrayAvailable = count;
size_t countBytes = count * sizeof(T);
size_t remainingBytes = (size_t)(mat->total() - idx2Offset(mat, tempIndices))*mat->elemSize();
countBytes = (countBytes>remainingBytes)?remainingBytes:countBytes;
int result = (int)countBytes;
int matAvailable = getMatAvailable(mat, tempIndices);
int available = MIN(arrayAvailable, matAvailable);
if (mat->isContinuous()) {
memcpy(mat->ptr(tempIndices.data()), tBuffer, available * sizeof(T));
} else {
char* buff = (char*)tBuffer;
size_t blockSize = mat->size[mat->dims-1] * mat->elemSize();
size_t firstPartialBlockSize = (mat->size[mat->dims-1] - tempIndices[mat->dims-1]) * mat->step[mat->dims-1];
for (int dim=mat->dims-2; dim>=0 && blockSize == mat->step[dim]; dim--) {
blockSize *= mat->size[dim];
firstPartialBlockSize += (mat->size[dim] - (tempIndices[dim]+1)) * mat->step[dim];
}
size_t copyCount = (countBytes<firstPartialBlockSize)?countBytes:firstPartialBlockSize;
uchar* data = mat->ptr(tempIndices.data());
while(countBytes>0){
memcpy(data, buff, copyCount);
updateIdx(mat, tempIndices, copyCount / mat->elemSize());
countBytes -= copyCount;
buff += copyCount;
copyCount = countBytes<blockSize?countBytes:blockSize;
data = mat->ptr(tempIndices.data());
}
}
return result;
}
- (int)put:(NSArray<NSNumber*>*)indices count:(int)count byteBuffer:(const char*)buffer {
int depth = _nativePtr->depth();
if (depth != CV_8U && depth != CV_8S) {
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Invalid depth (%@). Valid depths for this call are CV_8U or CV_8S.", [CvType typeToString:depth]]
userInfo:nil];
@throw exception;
}
return putData(indices, _nativePtr, count, buffer);
}
- (int)put:(NSArray<NSNumber*>*)indices count:(int)count doubleBuffer:(const double*)buffer {
int depth = _nativePtr->depth();
if (depth != CV_64F) {
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Invalid depth (%@). Valid depth for this call is CV_64F.", [CvType typeToString:depth]]
userInfo:nil];
@throw exception;
}
return putData(indices, _nativePtr, count, buffer);
}
- (int)put:(NSArray<NSNumber*>*)indices count:(int)count floatBuffer:(const float*)buffer {
int depth = _nativePtr->depth();
if (depth != CV_32F) {
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Invalid depth (%@). Valid depth for this call is CV_32F.", [CvType typeToString:depth]]
userInfo:nil];
@throw exception;
}
return putData(indices, _nativePtr, count, buffer);
}
- (int)put:(NSArray<NSNumber*>*)indices count:(int)count intBuffer:(const int*)buffer {
int depth = _nativePtr->depth();
if (depth != CV_32S) {
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Invalid depth (%@). Valid depth for this call is CV_32S.", [CvType typeToString:depth]]
userInfo:nil];
@throw exception;
}
return putData(indices, _nativePtr, count, buffer);
}
- (int)put:(NSArray<NSNumber*>*)indices count:(int)count shortBuffer:(const short*)buffer {
int depth = _nativePtr->depth();
if (depth != CV_16S && depth != CV_16U) {
NSException* exception = [NSException
exceptionWithName:@"UnsupportedOperationException"
reason:[NSString stringWithFormat:@"Invalid depth (%@). Valid depths for this call are CV_16S and CV_16U.", [CvType typeToString:depth]]
userInfo:nil];
@throw exception;
}
return putData(indices, _nativePtr, count, buffer);
}
- (int)height {
return [self rows];
}
- (int)width {
return [self cols];
}
@end

View File

@ -0,0 +1,723 @@
//
// MatExt.swift
//
// Created by Giles Payne on 2020/01/19.
//
import Foundation
let OpenCVErrorDomain = "OpenCVErrorDomain"
enum OpenCVError : Int {
case IncompatibleDataType = 10001
case IncompatibleBufferSize
}
func throwIncompatibleDataType(typeName: String) throws {
throw NSError(
domain: OpenCVErrorDomain,
code: OpenCVError.IncompatibleDataType.rawValue,
userInfo: [
NSLocalizedDescriptionKey: "Incompatible Mat type \(typeName)"
]
)
}
func throwIncompatibleBufferSize(count: Int, channels: Int32) throws {
throw NSError(
domain: OpenCVErrorDomain,
code: OpenCVError.IncompatibleBufferSize.rawValue,
userInfo: [
NSLocalizedDescriptionKey: "Provided data element number \(count) should be multiple of the Mat channels count \(channels)"
]
)
}
public typealias T2<T> = (T, T)
public typealias T3<T> = (T, T, T)
public typealias T4<T> = (T, T, T, T)
public extension Mat {
convenience init(rows:Int32, cols:Int32, type:Int32, data:[Int8]) {
let dataObject = data.withUnsafeBufferPointer { Data(buffer: $0) }
self.init(rows: rows, cols: cols, type: type, data: dataObject)
}
convenience init(rows:Int32, cols:Int32, type:Int32, data:[Int8], step:Int) {
let dataObject = data.withUnsafeBufferPointer { Data(buffer: $0) }
self.init(rows: rows, cols: cols, type: type, data: dataObject, step:step)
}
@discardableResult func get(indices:[Int32], data:inout [Int8]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
} else if depth() != CvType.CV_8U && depth() != CvType.CV_8S {
try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
}
let count = Int32(data.count)
return data.withUnsafeMutableBufferPointer { body in
return __get(indices as [NSNumber], count: count, byteBuffer: body.baseAddress!)
}
}
@discardableResult func get(indices:[Int32], data:inout [UInt8]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
} else if depth() != CvType.CV_8U {
try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
}
let count = Int32(data.count)
return data.withUnsafeMutableBufferPointer { body in
body.withMemoryRebound(to: Int8.self) { reboundBody in
return __get(indices as [NSNumber], count: count, byteBuffer: reboundBody.baseAddress!)
}
}
}
@discardableResult func get(indices:[Int32], data:inout [Double]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
} else if depth() != CvType.CV_64F {
try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
}
let count = Int32(data.count)
return data.withUnsafeMutableBufferPointer { body in
return __get(indices as [NSNumber], count: count, doubleBuffer: body.baseAddress!)
}
}
@discardableResult func get(indices:[Int32], data:inout [Float]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
} else if depth() != CvType.CV_32F {
try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
}
let count = Int32(data.count)
return data.withUnsafeMutableBufferPointer { body in
return __get(indices as [NSNumber], count: count, floatBuffer: body.baseAddress!)
}
}
@discardableResult func get(indices:[Int32], data:inout [Int32]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
} else if depth() != CvType.CV_32S {
try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
}
let count = Int32(data.count)
return data.withUnsafeMutableBufferPointer { body in
return __get(indices as [NSNumber], count: count, intBuffer: body.baseAddress!)
}
}
@discardableResult func get(indices:[Int32], data:inout [Int16]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
} else if depth() != CvType.CV_16U && depth() != CvType.CV_16S {
try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
}
let count = Int32(data.count)
return data.withUnsafeMutableBufferPointer { body in
return __get(indices as [NSNumber], count: count, shortBuffer: body.baseAddress!)
}
}
@discardableResult func get(indices:[Int32], data:inout [UInt16]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
} else if depth() != CvType.CV_16U {
try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
}
let count = Int32(data.count)
return data.withUnsafeMutableBufferPointer { body in
body.withMemoryRebound(to: Int16.self) { reboundBody in
return __get(indices as [NSNumber], count: count, shortBuffer: reboundBody.baseAddress!)
}
}
}
@discardableResult func get(row: Int32, col: Int32, data:inout [Int8]) throws -> Int32 {
return try get(indices: [row, col], data: &data)
}
@discardableResult func get(row: Int32, col: Int32, data:inout [UInt8]) throws -> Int32 {
return try get(indices: [row, col], data: &data)
}
@discardableResult func get(row: Int32, col: Int32, data:inout [Double]) throws -> Int32 {
return try get(indices: [row, col], data: &data)
}
@discardableResult func get(row: Int32, col: Int32, data:inout [Float]) throws -> Int32 {
return try get(indices: [row, col], data: &data)
}
@discardableResult func get(row: Int32, col: Int32, data:inout [Int32]) throws -> Int32 {
return try get(indices: [row, col], data: &data)
}
@discardableResult func get(row: Int32, col: Int32, data:inout [Int16]) throws -> Int32 {
return try get(indices: [row, col], data: &data)
}
@discardableResult func get(row: Int32, col: Int32, data:inout [UInt16]) throws -> Int32 {
return try get(indices: [row, col], data: &data)
}
@discardableResult func put(indices:[Int32], data:[Int8]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
} else if depth() != CvType.CV_8U && depth() != CvType.CV_8S {
try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
}
let count = Int32(data.count)
return data.withUnsafeBufferPointer { body in
return __put(indices as [NSNumber], count: count, byteBuffer: body.baseAddress!)
}
}
@discardableResult func put(indices:[Int32], data:[UInt8]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
} else if depth() != CvType.CV_8U {
try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
}
let count = Int32(data.count)
return data.withUnsafeBufferPointer { body in
body.withMemoryRebound(to: Int8.self) { reboundBody in
return __put(indices as [NSNumber], count: count, byteBuffer: reboundBody.baseAddress!)
}
}
}
@discardableResult func put(indices:[Int32], data:[Int8], offset: Int, length: Int32) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
} else if depth() != CvType.CV_8U && depth() != CvType.CV_8S {
try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
}
return data.withUnsafeBufferPointer { body in
return __put(indices as [NSNumber], count: length, byteBuffer: body.baseAddress! + offset)
}
}
// unlike other put:indices:data functions this one (with [Double]) should convert input values to correct type
@discardableResult func put(indices:[Int32], data:[Double]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
}
if depth() == CvType.CV_64F {
let count = Int32(data.count)
return data.withUnsafeBufferPointer { body in
return __put(indices as [NSNumber], count: count, doubleBuffer: body.baseAddress!)
}
} else {
return __put(indices as [NSNumber], data: data as [NSNumber])
}
}
@discardableResult func put(indices:[Int32], data:[Float]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
} else if depth() != CvType.CV_32F {
try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
}
let count = Int32(data.count)
return data.withUnsafeBufferPointer { body in
return __put(indices as [NSNumber], count: count, floatBuffer: body.baseAddress!)
}
}
@discardableResult func put(indices:[Int32], data:[Int32]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
} else if depth() != CvType.CV_32S {
try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
}
let count = Int32(data.count)
return data.withUnsafeBufferPointer { body in
return __put(indices as [NSNumber], count: count, intBuffer: body.baseAddress!)
}
}
@discardableResult func put(indices:[Int32], data:[Int16]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
} else if depth() != CvType.CV_16U && depth() != CvType.CV_16S {
try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
}
let count = Int32(data.count)
return data.withUnsafeBufferPointer { body in
return __put(indices as [NSNumber], count: count, shortBuffer: body.baseAddress!)
}
}
@discardableResult func put(indices:[Int32], data:[UInt16]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
} else if depth() != CvType.CV_16U {
try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
}
let count = Int32(data.count)
return data.withUnsafeBufferPointer { body in
body.withMemoryRebound(to: Int16.self) { reboundBody in
return __put(indices as [NSNumber], count: count, shortBuffer: reboundBody.baseAddress!)
}
}
}
@discardableResult func put(row: Int32, col: Int32, data:[Int8]) throws -> Int32 {
return try put(indices: [row, col], data: data)
}
@discardableResult func put(row: Int32, col: Int32, data:[UInt8]) throws -> Int32 {
return try put(indices: [row, col], data: data)
}
@discardableResult func put(row: Int32, col: Int32, data: [Int8], offset: Int, length: Int32) throws -> Int32 {
return try put(indices: [row, col], data: data, offset: offset, length: length)
}
@discardableResult func put(row: Int32, col: Int32, data: [Double]) throws -> Int32 {
return try put(indices: [row, col], data: data)
}
@discardableResult func put(row: Int32, col: Int32, data: [Float]) throws -> Int32 {
return try put(indices: [row, col], data: data)
}
@discardableResult func put(row: Int32, col: Int32, data: [Int32]) throws -> Int32 {
return try put(indices: [row, col], data: data)
}
@discardableResult func put(row: Int32, col: Int32, data: [Int16]) throws -> Int32 {
return try put(indices: [row, col], data: data)
}
@discardableResult func put(row: Int32, col: Int32, data: [UInt16]) throws -> Int32 {
return try put(indices: [row, col], data: data)
}
@discardableResult func get(row: Int32, col: Int32) -> [Double] {
return get(indices: [row, col])
}
@discardableResult func get(indices: [Int32]) -> [Double] {
return __get(indices as [NSNumber]) as! [Double]
}
}
public protocol Atable {
static func getAt(m: Mat, indices:[Int32]) -> Self
static func putAt(m: Mat, indices:[Int32], v: Self)
static func getAt2c(m: Mat, indices:[Int32]) -> (Self, Self)
static func putAt2c(m: Mat, indices:[Int32], v: (Self, Self))
static func getAt3c(m: Mat, indices:[Int32]) -> (Self, Self, Self)
static func putAt3c(m: Mat, indices:[Int32], v: (Self, Self, Self))
static func getAt4c(m: Mat, indices:[Int32]) -> (Self, Self, Self, Self)
static func putAt4c(m: Mat, indices:[Int32], v: (Self, Self, Self, Self))
}
public class MatAt<N: Atable> {
init(mat: Mat, indices: [Int32]) {
self.mat = mat
self.indices = indices
}
private let mat: Mat
private let indices: [Int32]
public var v: N {
get {
return N.getAt(m: mat, indices: indices)
}
set(value) {
N.putAt(m: mat, indices: indices, v: value)
}
}
public var v2c: (N, N) {
get {
return N.getAt2c(m: mat, indices: indices)
}
set(value) {
N.putAt2c(m: mat, indices: indices, v: value)
}
}
public var v3c: (N, N, N) {
get {
return N.getAt3c(m: mat, indices: indices)
}
set(value) {
N.putAt3c(m: mat, indices: indices, v: value)
}
}
public var v4c: (N, N, N, N) {
get {
return N.getAt4c(m: mat, indices: indices)
}
set(value) {
N.putAt4c(m: mat, indices: indices, v: value)
}
}
}
extension UInt8: Atable {
public static func getAt(m: Mat, indices:[Int32]) -> UInt8 {
var tmp = [UInt8](repeating: 0, count: 1)
try! m.get(indices: indices, data: &tmp)
return tmp[0]
}
public static func putAt(m: Mat, indices: [Int32], v: UInt8) {
let tmp = [v]
try! m.put(indices: indices, data: tmp)
}
public static func getAt2c(m: Mat, indices:[Int32]) -> (UInt8, UInt8) {
var tmp = [UInt8](repeating: 0, count: 2)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1])
}
public static func putAt2c(m: Mat, indices: [Int32], v: (UInt8, UInt8)) {
let tmp = [v.0, v.1]
try! m.put(indices: indices, data: tmp)
}
public static func getAt3c(m: Mat, indices:[Int32]) -> (UInt8, UInt8, UInt8) {
var tmp = [UInt8](repeating: 0, count: 3)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1], tmp[2])
}
public static func putAt3c(m: Mat, indices: [Int32], v: (UInt8, UInt8, UInt8)) {
let tmp = [v.0, v.1, v.2]
try! m.put(indices: indices, data: tmp)
}
public static func getAt4c(m: Mat, indices:[Int32]) -> (UInt8, UInt8, UInt8, UInt8) {
var tmp = [UInt8](repeating: 0, count: 4)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1], tmp[2], tmp[3])
}
public static func putAt4c(m: Mat, indices: [Int32], v: (UInt8, UInt8, UInt8, UInt8)) {
let tmp = [v.0, v.1, v.2, v.3]
try! m.put(indices: indices, data: tmp)
}
}
extension Int8: Atable {
public static func getAt(m: Mat, indices:[Int32]) -> Int8 {
var tmp = [Int8](repeating: 0, count: 1)
try! m.get(indices: indices, data: &tmp)
return tmp[0]
}
public static func putAt(m: Mat, indices: [Int32], v: Int8) {
let tmp = [v]
try! m.put(indices: indices, data: tmp)
}
public static func getAt2c(m: Mat, indices:[Int32]) -> (Int8, Int8) {
var tmp = [Int8](repeating: 0, count: 2)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1])
}
public static func putAt2c(m: Mat, indices: [Int32], v: (Int8, Int8)) {
let tmp = [v.0, v.1]
try! m.put(indices: indices, data: tmp)
}
public static func getAt3c(m: Mat, indices:[Int32]) -> (Int8, Int8, Int8) {
var tmp = [Int8](repeating: 0, count: 3)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1], tmp[2])
}
public static func putAt3c(m: Mat, indices: [Int32], v: (Int8, Int8, Int8)) {
let tmp = [v.0, v.1, v.2]
try! m.put(indices: indices, data: tmp)
}
public static func getAt4c(m: Mat, indices:[Int32]) -> (Int8, Int8, Int8, Int8) {
var tmp = [Int8](repeating: 0, count: 4)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1], tmp[2], tmp[3])
}
public static func putAt4c(m: Mat, indices: [Int32], v: (Int8, Int8, Int8, Int8)) {
let tmp = [v.0, v.1, v.2, v.3]
try! m.put(indices: indices, data: tmp)
}
}
extension Double: Atable {
public static func getAt(m: Mat, indices:[Int32]) -> Double {
var tmp = [Double](repeating: 0, count: 1)
try! m.get(indices: indices, data: &tmp)
return tmp[0]
}
public static func putAt(m: Mat, indices: [Int32], v: Double) {
let tmp = [v]
try! m.put(indices: indices, data: tmp)
}
public static func getAt2c(m: Mat, indices:[Int32]) -> (Double, Double) {
var tmp = [Double](repeating: 0, count: 2)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1])
}
public static func putAt2c(m: Mat, indices: [Int32], v: (Double, Double)) {
let tmp = [v.0, v.1]
try! m.put(indices: indices, data: tmp)
}
public static func getAt3c(m: Mat, indices:[Int32]) -> (Double, Double, Double) {
var tmp = [Double](repeating: 0, count: 3)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1], tmp[2])
}
public static func putAt3c(m: Mat, indices: [Int32], v: (Double, Double, Double)) {
let tmp = [v.0, v.1, v.2]
try! m.put(indices: indices, data: tmp)
}
public static func getAt4c(m: Mat, indices:[Int32]) -> (Double, Double, Double, Double) {
var tmp = [Double](repeating: 0, count: 4)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1], tmp[2], tmp[3])
}
public static func putAt4c(m: Mat, indices: [Int32], v: (Double, Double, Double, Double)) {
let tmp = [v.0, v.1, v.2, v.3]
try! m.put(indices: indices, data: tmp)
}
}
extension Float: Atable {
public static func getAt(m: Mat, indices:[Int32]) -> Float {
var tmp = [Float](repeating: 0, count: 1)
try! m.get(indices: indices, data: &tmp)
return tmp[0]
}
public static func putAt(m: Mat, indices: [Int32], v: Float) {
let tmp = [v]
try! m.put(indices: indices, data: tmp)
}
public static func getAt2c(m: Mat, indices:[Int32]) -> (Float, Float) {
var tmp = [Float](repeating: 0, count: 2)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1])
}
public static func putAt2c(m: Mat, indices: [Int32], v: (Float, Float)) {
let tmp = [v.0, v.1]
try! m.put(indices: indices, data: tmp)
}
public static func getAt3c(m: Mat, indices:[Int32]) -> (Float, Float, Float) {
var tmp = [Float](repeating: 0, count: 3)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1], tmp[2])
}
public static func putAt3c(m: Mat, indices: [Int32], v: (Float, Float, Float)) {
let tmp = [v.0, v.1, v.2]
try! m.put(indices: indices, data: tmp)
}
public static func getAt4c(m: Mat, indices:[Int32]) -> (Float, Float, Float, Float) {
var tmp = [Float](repeating: 0, count: 4)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1], tmp[2], tmp[3])
}
public static func putAt4c(m: Mat, indices: [Int32], v: (Float, Float, Float, Float)) {
let tmp = [v.0, v.1, v.2, v.3]
try! m.put(indices: indices, data: tmp)
}
}
extension Int32: Atable {
public static func getAt(m: Mat, indices:[Int32]) -> Int32 {
var tmp = [Int32](repeating: 0, count: 1)
try! m.get(indices: indices, data: &tmp)
return tmp[0]
}
public static func putAt(m: Mat, indices: [Int32], v: Int32) {
let tmp = [v]
try! m.put(indices: indices, data: tmp)
}
public static func getAt2c(m: Mat, indices:[Int32]) -> (Int32, Int32) {
var tmp = [Int32](repeating: 0, count: 2)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1])
}
public static func putAt2c(m: Mat, indices: [Int32], v: (Int32, Int32)) {
let tmp = [v.0, v.1]
try! m.put(indices: indices, data: tmp)
}
public static func getAt3c(m: Mat, indices:[Int32]) -> (Int32, Int32, Int32) {
var tmp = [Int32](repeating: 0, count: 3)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1], tmp[2])
}
public static func putAt3c(m: Mat, indices: [Int32], v: (Int32, Int32, Int32)) {
let tmp = [v.0, v.1, v.2]
try! m.put(indices: indices, data: tmp)
}
public static func getAt4c(m: Mat, indices:[Int32]) -> (Int32, Int32, Int32, Int32) {
var tmp = [Int32](repeating: 0, count: 4)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1], tmp[2], tmp[3])
}
public static func putAt4c(m: Mat, indices: [Int32], v: (Int32, Int32, Int32, Int32)) {
let tmp = [v.0, v.1, v.2, v.3]
try! m.put(indices: indices, data: tmp)
}
}
extension UInt16: Atable {
public static func getAt(m: Mat, indices:[Int32]) -> UInt16 {
var tmp = [UInt16](repeating: 0, count: 1)
try! m.get(indices: indices, data: &tmp)
return tmp[0]
}
public static func putAt(m: Mat, indices: [Int32], v: UInt16) {
let tmp = [v]
try! m.put(indices: indices, data: tmp)
}
public static func getAt2c(m: Mat, indices:[Int32]) -> (UInt16, UInt16) {
var tmp = [UInt16](repeating: 0, count: 2)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1])
}
public static func putAt2c(m: Mat, indices: [Int32], v: (UInt16, UInt16)) {
let tmp = [v.0, v.1]
try! m.put(indices: indices, data: tmp)
}
public static func getAt3c(m: Mat, indices:[Int32]) -> (UInt16, UInt16, UInt16) {
var tmp = [UInt16](repeating: 0, count: 3)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1], tmp[2])
}
public static func putAt3c(m: Mat, indices: [Int32], v: (UInt16, UInt16, UInt16)) {
let tmp = [v.0, v.1, v.2]
try! m.put(indices: indices, data: tmp)
}
public static func getAt4c(m: Mat, indices:[Int32]) -> (UInt16, UInt16, UInt16, UInt16) {
var tmp = [UInt16](repeating: 0, count: 4)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1], tmp[2], tmp[3])
}
public static func putAt4c(m: Mat, indices: [Int32], v: (UInt16, UInt16, UInt16, UInt16)) {
let tmp = [v.0, v.1, v.2, v.3]
try! m.put(indices: indices, data: tmp)
}
}
extension Int16: Atable {
public static func getAt(m: Mat, indices:[Int32]) -> Int16 {
var tmp = [Int16](repeating: 0, count: 1)
try! m.get(indices: indices, data: &tmp)
return tmp[0]
}
public static func putAt(m: Mat, indices: [Int32], v: Int16) {
let tmp = [v]
try! m.put(indices: indices, data: tmp)
}
public static func getAt2c(m: Mat, indices:[Int32]) -> (Int16, Int16) {
var tmp = [Int16](repeating: 0, count: 2)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1])
}
public static func putAt2c(m: Mat, indices: [Int32], v: (Int16, Int16)) {
let tmp = [v.0, v.1]
try! m.put(indices: indices, data: tmp)
}
public static func getAt3c(m: Mat, indices:[Int32]) -> (Int16, Int16, Int16) {
var tmp = [Int16](repeating: 0, count: 3)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1], tmp[2])
}
public static func putAt3c(m: Mat, indices: [Int32], v: (Int16, Int16, Int16)) {
let tmp = [v.0, v.1, v.2]
try! m.put(indices: indices, data: tmp)
}
public static func getAt4c(m: Mat, indices:[Int32]) -> (Int16, Int16, Int16, Int16) {
var tmp = [Int16](repeating: 0, count: 4)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1], tmp[2], tmp[3])
}
public static func putAt4c(m: Mat, indices: [Int32], v: (Int16, Int16, Int16, Int16)) {
let tmp = [v.0, v.1, v.2, v.3]
try! m.put(indices: indices, data: tmp)
}
}
/***
* Example use:
*
* let elemantVal: UInt8 = mat.at(row: 50, col: 50).v
* mat.at(row: 50, col: 50).v = 245
*
*/
public extension Mat {
func at<N: Atable>(row: Int32, col: Int32) -> MatAt<N> {
return MatAt(mat: self, indices: [row, col])
}
func at<N: Atable>(indices:[Int32]) -> MatAt<N> {
return MatAt(mat: self, indices: indices)
}
}
public extension Mat {
static func *(lhs:Mat, rhs: Mat) -> Mat {
return lhs.matMul(rhs)
}
}

View File

@ -0,0 +1,62 @@
//
// MatOfByte.h
//
// Created by Giles Payne on 2019/12/26.
//
#pragma once
#import "Mat.h"
NS_ASSUME_NONNULL_BEGIN
/**
* Mat representation of an array of bytes
*/
CV_EXPORTS @interface MatOfByte : Mat
#pragma mark - Constructors
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat;
#endif
/**
* Create MatOfByte from Mat object
* @param mat Mat object from which to create MatOfByte
*/
- (instancetype)initWithMat:(Mat*)mat;
/**
* Create MatOfByte from array
* @param array Array from which to create MatOfByte
*/
- (instancetype)initWithArray:(NSArray<NSNumber*>*)array;
#pragma mark - Methods
/**
* Allocate specified number of elements
* @param elemNumber Number of elements
*/
- (void)alloc:(int)elemNumber;
/**
* Populate Mat with elements of an array
* @param array Array with which to populate the Mat
*/
- (void)fromArray:(NSArray<NSNumber*>*)array;
/**
* Output Mat elements as an array
*/
- (NSArray<NSNumber*>*)toArray;
/**
* Total number of values in Mat
*/
- (int)length;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,69 @@
//
// MatOfByte.mm
//
// Created by Giles Payne on 2019/12/26.
//
#import "MatOfByte.h"
#import "Range.h"
#import "CvType.h"
#import "ArrayUtil.h"
@implementation MatOfByte
static const int _depth = CV_8U;
static const int _channels = 1;
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat {
self = [super initWithNativeMat:nativeMat];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
#endif
- (instancetype)initWithMat:(Mat*)mat {
self = [super initWithMat:mat rowRange:[Range all]];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
- (instancetype)initWithArray:(NSArray<NSNumber*>*)array {
self = [super init];
if (self) {
[self fromArray:array];
}
return self;
}
- (void)alloc:(int)elemNumber {
if (elemNumber>0) {
[super create:elemNumber cols:1 type:[CvType makeType:_depth channels:_channels]];
}
}
- (void)fromArray:(NSArray<NSNumber*>*)array {
[self alloc:(int)array.count / _channels];
[self put:0 col:0 data:array];
}
- (NSArray<NSNumber*>*)toArray {
int length = [self length];
NSMutableArray<NSNumber*>* data = createArrayWithSize(length, @0.0);
[self get:0 col:0 data:data];
return data;
}
- (int)length {
int num = [self checkVector:_channels depth:_depth];
if (num < 0) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Incompatible Mat" userInfo:nil];
}
return num * _channels;
}
@end

View File

@ -0,0 +1,64 @@
//
// MatOfDMatch.h
//
// Created by Giles Payne on 2019/12/27.
//
#pragma once
#import "Mat.h"
@class DMatch;
NS_ASSUME_NONNULL_BEGIN
/**
* Mat representation of an array of DMatch objects
*/
CV_EXPORTS @interface MatOfDMatch : Mat
#pragma mark - Constructors
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat;
#endif
/**
* Create MatOfDMatch from Mat object
* @param mat Mat object from which to create MatOfDMatch
*/
- (instancetype)initWithMat:(Mat*)mat;
/**
* Create MatOfDMatch from array
* @param array Array from which to create MatOfDMatch
*/
- (instancetype)initWithArray:(NSArray<DMatch*>*)array;
#pragma mark - Methods
/**
* Allocate specified number of elements
* @param elemNumber Number of elements
*/
- (void)alloc:(int)elemNumber;
/**
* Populate Mat with elements of an array
* @param array Array with which to populate the Mat
*/
- (void)fromArray:(NSArray<DMatch*>*)array;
/**
* Output Mat elements as an array of DMatch objects
*/
- (NSArray<DMatch*>*)toArray;
/**
* Total number of values in Mat
*/
- (int)length;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,83 @@
//
// MatOfDMatch.m
//
// Created by Giles Payne on 2019/12/27.
//
#import "MatOfDMatch.h"
#import "Range.h"
#import "DMatch.h"
#import "CvType.h"
#import "ArrayUtil.h"
@implementation MatOfDMatch
static const int _depth = CV_32F;
static const int _channels = 4;
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat {
self = [super initWithNativeMat:nativeMat];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
#endif
- (instancetype)initWithMat:(Mat*)mat {
self = [super initWithMat:mat rowRange:[Range all]];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
- (instancetype)initWithArray:(NSArray<DMatch*>*)array {
self = [super init];
if (self) {
[self fromArray:array];
}
return self;
}
- (void)alloc:(int)elemNumber {
if (elemNumber>0) {
[super create:elemNumber cols:1 type:[CvType makeType:_depth channels:_channels]];
}
}
- (void)fromArray:(NSArray<DMatch*>*)array {
NSMutableArray<NSNumber*>* data = [[NSMutableArray alloc] initWithCapacity:array.count * _channels];
for (int index = 0; index < (int)array.count; index++) {
data[_channels * index] = [NSNumber numberWithFloat:array[index].queryIdx];
data[_channels * index + 1] = [NSNumber numberWithFloat:array[index].trainIdx];
data[_channels * index + 2] = [NSNumber numberWithFloat:array[index].imgIdx];
data[_channels * index + 3] = [NSNumber numberWithFloat:array[index].distance];
}
[self alloc:(int)array.count];
[self put:0 col:0 data:data];
}
- (NSArray<DMatch*>*)toArray {
int length = [self length] / _channels;
NSMutableArray<DMatch*>* ret = createArrayWithSize(length, [DMatch new]);
if (length > 0) {
NSMutableArray<NSNumber*>* data = createArrayWithSize([self length], @0.0);
[self get:0 col:0 data:data];
for (int index = 0; index < length; index++) {
ret[index] = [[DMatch alloc] initWithQueryIdx:data[index * _channels].intValue trainIdx:data[index * _channels + 1].intValue imgIdx:data[index * _channels + 2].intValue distance:data[index * _channels + 3].floatValue];
}
}
return ret;
}
- (int)length {
int num = [self checkVector:_channels depth:_depth];
if (num < 0) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Incompatible Mat" userInfo:nil];
}
return num * _channels;
}
@end

View File

@ -0,0 +1,63 @@
//
// MatOfDouble.h
//
// Created by Giles Payne on 2019/12/26.
//
#pragma once
#import "Mat.h"
NS_ASSUME_NONNULL_BEGIN
/**
* Mat representation of an array of doubles
*/
CV_EXPORTS @interface MatOfDouble : Mat
#pragma mark - Constructors
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat;
#endif
/**
* Create MatOfDouble from Mat object
* @param mat Mat object from which to create MatOfDouble
*/
- (instancetype)initWithMat:(Mat*)mat;
/**
* Create MatOfDouble from array
* @param array Array from which to create MatOfDouble
*/
- (instancetype)initWithArray:(NSArray<NSNumber*>*)array;
#pragma mark - Methods
/**
* Allocate specified number of elements
* @param elemNumber Number of elements
*/
- (void)alloc:(int)elemNumber;
/**
* Populate Mat with elements of an array
* @param array Array with which to populate the Mat
*/
- (void)fromArray:(NSArray<NSNumber*>*)array;
/**
* Output Mat elements as an array
*/
- (NSArray<NSNumber*>*)toArray;
/**
* Total number of values in Mat
*/
- (int)length;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,69 @@
//
// MatOfDouble.mm
//
// Created by Giles Payne on 2019/12/26.
//
#import "MatOfDouble.h"
#import "Range.h"
#import "CvType.h"
#import "ArrayUtil.h"
@implementation MatOfDouble
static const int _depth = CV_64F;
static const int _channels = 1;
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat {
self = [super initWithNativeMat:nativeMat];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
#endif
- (instancetype)initWithMat:(Mat*)mat {
self = [super initWithMat:mat rowRange:[Range all]];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
- (instancetype)initWithArray:(NSArray<NSNumber*>*)array {
self = [super init];
if (self) {
[self fromArray:array];
}
return self;
}
- (void)alloc:(int)elemNumber {
if (elemNumber>0) {
[super create:elemNumber cols:1 type:[CvType makeType:_depth channels:_channels]];
}
}
- (void)fromArray:(NSArray<NSNumber*>*)array {
[self alloc:(int)array.count / _channels];
[self put:0 col:0 data:array];
}
- (NSArray<NSNumber*>*)toArray {
int length = [self length];
NSMutableArray<NSNumber*>* data = createArrayWithSize(length, @0.0);
[self get:0 col:0 data:data];
return data;
}
- (int)length {
int num = [self checkVector:_channels depth:_depth];
if (num < 0) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Incompatible Mat" userInfo:nil];
}
return num * _channels;
}
@end

View File

@ -0,0 +1,60 @@
//
// MatOfFloat.h
//
// Created by Giles Payne on 2019/12/26.
//
#pragma once
#import "Mat.h"
NS_ASSUME_NONNULL_BEGIN
/**
* Mat representation of an array of floats
*/
CV_EXPORTS @interface MatOfFloat : Mat
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat;
#endif
/**
* Create MatOfFloat from Mat object
* @param mat Mat object from which to create MatOfFloat
*/
- (instancetype)initWithMat:(Mat*)mat;
/**
* Create MatOfFloat from array
* @param array Array from which to create MatOfFloat
*/
- (instancetype)initWithArray:(NSArray<NSNumber*>*)array;
#pragma mark - Methods
/**
* Allocate specified number of elements
* @param elemNumber Number of elements
*/
- (void)alloc:(int)elemNumber;
/**
* Populate Mat with elements of an array
* @param array Array with which to populate the Mat
*/
- (void)fromArray:(NSArray<NSNumber*>*)array;
/**
* Output Mat elements as an array
*/
- (NSArray<NSNumber*>*)toArray;
/**
* Total number of values in Mat
*/
- (int)length;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,69 @@
//
// MatOfFloat.mm
//
// Created by Giles Payne on 2019/12/26.
//
#import "MatOfFloat.h"
#import "Range.h"
#import "CvType.h"
#import "ArrayUtil.h"
@implementation MatOfFloat
static const int _depth = CV_32F;
static const int _channels = 1;
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat {
self = [super initWithNativeMat:nativeMat];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
#endif
- (instancetype)initWithMat:(Mat*)mat {
self = [super initWithMat:mat rowRange:[Range all]];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
- (instancetype)initWithArray:(NSArray<NSNumber*>*)array {
self = [super init];
if (self) {
[self fromArray:array];
}
return self;
}
- (void)alloc:(int)elemNumber {
if (elemNumber>0) {
[super create:elemNumber cols:1 type:[CvType makeType:_depth channels:_channels]];
}
}
- (void)fromArray:(NSArray<NSNumber*>*)array {
[self alloc:(int)array.count / _channels];
[self put:0 col:0 data:array];
}
- (NSArray<NSNumber*>*)toArray {
int length = [self length];
NSMutableArray<NSNumber*>* data = createArrayWithSize(length, @0.0);
[self get:0 col:0 data:data];
return data;
}
- (int)length {
int num = [self checkVector:_channels depth:_depth];
if (num < 0) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Incompatible Mat" userInfo:nil];
}
return num * _channels;
}
@end

View File

@ -0,0 +1,62 @@
//
// MatOfFloat4.h
//
// Created by Giles Payne on 2019/12/26.
//
#pragma once
#import "Mat.h"
NS_ASSUME_NONNULL_BEGIN
/**
* Mat representation of an array of vectors of four floats
*/
CV_EXPORTS @interface MatOfFloat4 : Mat
#pragma mark - Constructors
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat;
#endif
/**
* Create MatOfFloat4 from Mat object
* @param mat Mat object from which to create MatOfFloat4
*/
- (instancetype)initWithMat:(Mat*)mat;
/**
* Create MatOfFloat4 from array
* @param array Array from which to create MatOfFloat4
*/
- (instancetype)initWithArray:(NSArray<NSNumber*>*)array;
#pragma mark - Methods
/**
* Allocate specified number of elements
* @param elemNumber Number of elements
*/
- (void)alloc:(int)elemNumber;
/**
* Populate Mat with elements of an array
* @param array Array with which to populate the Mat
*/
- (void)fromArray:(NSArray<NSNumber*>*)array;
/**
* Output Mat elements as an array
*/
- (NSArray<NSNumber*>*)toArray;
/**
* Total number of values in Mat
*/
- (int)length;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,69 @@
//
// MatOfFloat4.mm
//
// Created by Giles Payne on 2019/12/26.
//
#import "MatOfFloat4.h"
#import "Range.h"
#import "CvType.h"
#import "ArrayUtil.h"
@implementation MatOfFloat4
static const int _depth = CV_32F;
static const int _channels = 4;
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat {
self = [super initWithNativeMat:nativeMat];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
#endif
- (instancetype)initWithMat:(Mat*)mat {
self = [super initWithMat:mat rowRange:[Range all]];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
- (instancetype)initWithArray:(NSArray<NSNumber*>*)array {
self = [super init];
if (self) {
[self fromArray:array];
}
return self;
}
- (void)alloc:(int)elemNumber {
if (elemNumber>0) {
[super create:elemNumber cols:1 type:[CvType makeType:_depth channels:_channels]];
}
}
- (void)fromArray:(NSArray<NSNumber*>*)array {
[self alloc:(int)array.count / _channels];
[self put:0 col:0 data:array];
}
- (NSArray<NSNumber*>*)toArray {
int length = [self length];
NSMutableArray<NSNumber*>* data = [[NSMutableArray alloc] initWithCapacity:length];
[self get:0 col:0 data:data];
return data;
}
- (int)length {
int num = [self checkVector:_channels depth:_depth];
if (num < 0) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Incompatible Mat" userInfo:nil];
}
return num * _channels;
}
@end

View File

@ -0,0 +1,62 @@
//
// MatOfFloat6.h
//
// Created by Giles Payne on 2019/12/26.
//
#pragma once
#import "Mat.h"
NS_ASSUME_NONNULL_BEGIN
/**
* Mat representation of an array of vectors of six floats
*/
CV_EXPORTS @interface MatOfFloat6 : Mat
#pragma mark - Constructors
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat;
#endif
/**
* Create MatOfFloat6 from Mat object
* @param mat Mat object from which to create MatOfFloat6
*/
- (instancetype)initWithMat:(Mat*)mat;
/**
* Create MatOfFloat6 from array
* @param array Array from which to create MatOfFloat6
*/
- (instancetype)initWithArray:(NSArray<NSNumber*>*)array;
#pragma mark - Methods
/**
* Allocate specified number of elements
* @param elemNumber Number of elements
*/
- (void)alloc:(int)elemNumber;
/**
* Populate Mat with elements of an array
* @param array Array with which to populate the Mat
*/
- (void)fromArray:(NSArray<NSNumber*>*)array;
/**
* Output Mat elements as an array
*/
- (NSArray<NSNumber*>*)toArray;
/**
* Total number of values in Mat
*/
- (int)length;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,69 @@
//
// MatOfFloat6.mm
//
// Created by Giles Payne on 2019/12/26.
//
#import "MatOfFloat6.h"
#import "Range.h"
#import "CvType.h"
#import "ArrayUtil.h"
@implementation MatOfFloat6
static const int _depth = CV_32F;
static const int _channels = 6;
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat {
self = [super initWithNativeMat:nativeMat];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
#endif
- (instancetype)initWithMat:(Mat*)mat {
self = [super initWithMat:mat rowRange:[Range all]];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
- (instancetype)initWithArray:(NSArray<NSNumber*>*)array {
self = [super init];
if (self) {
[self fromArray:array];
}
return self;
}
- (void)alloc:(int)elemNumber {
if (elemNumber>0) {
[super create:elemNumber cols:1 type:[CvType makeType:_depth channels:_channels]];
}
}
- (void)fromArray:(NSArray<NSNumber*>*)array {
[self alloc:(int)array.count / _channels];
[self put:0 col:0 data:array];
}
- (NSArray<NSNumber*>*)toArray {
int length = [self length];
NSMutableArray<NSNumber*>* data = [[NSMutableArray alloc] initWithCapacity:length];
[self get:0 col:0 data:data];
return data;
}
- (int)length {
int num = [self checkVector:_channels depth:_depth];
if (num < 0) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Incompatible Mat" userInfo:nil];
}
return num * _channels;
}
@end

View File

@ -0,0 +1,62 @@
//
// MatOfInt.h
//
// Created by Giles Payne on 2019/12/26.
//
#pragma once
#import "Mat.h"
NS_ASSUME_NONNULL_BEGIN
/**
* Mat representation of an array of ints
*/
CV_EXPORTS @interface MatOfInt : Mat
#pragma mark - Constructors
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat;
#endif
/**
* Create MatOfInt from Mat object
* @param mat Mat object from which to create MatOfInt
*/
- (instancetype)initWithMat:(Mat*)mat;
/**
* Create MatOfInt from array
* @param array Array from which to create MatOfInt
*/
- (instancetype)initWithArray:(NSArray<NSNumber*>*)array;
#pragma mark - Methods
/**
* Allocate specified number of elements
* @param elemNumber Number of elements
*/
- (void)alloc:(int)elemNumber;
/**
* Populate Mat with elements of an array
* @param array Array with which to populate the Mat
*/
- (void)fromArray:(NSArray<NSNumber*>*)array;
/**
* Output Mat elements as an array
*/
- (NSArray<NSNumber*>*)toArray;
/**
* Total number of values in Mat
*/
- (int)length;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,69 @@
//
// MatOfInt.mm
//
// Created by Giles Payne on 2019/12/26.
//
#import "MatOfInt.h"
#import "Range.h"
#import "CvType.h"
#import "ArrayUtil.h"
@implementation MatOfInt
static const int _depth = CV_32S;
static const int _channels = 1;
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat {
self = [super initWithNativeMat:nativeMat];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
#endif
- (instancetype)initWithMat:(Mat*)mat {
self = [super initWithMat:mat rowRange:[Range all]];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
- (instancetype)initWithArray:(NSArray<NSNumber*>*)array {
self = [super init];
if (self) {
[self fromArray:array];
}
return self;
}
- (void)alloc:(int)elemNumber {
if (elemNumber>0) {
[super create:elemNumber cols:1 type:[CvType makeType:_depth channels:_channels]];
}
}
- (void)fromArray:(NSArray<NSNumber*>*)array {
[self alloc:(int)array.count / _channels];
[self put:0 col:0 data:array];
}
- (NSArray<NSNumber*>*)toArray {
int length = [self length];
NSMutableArray<NSNumber*>* data = createArrayWithSize(length, @0.0);
[self get:0 col:0 data:data];
return data;
}
- (int)length {
int num = [self checkVector:_channels depth:_depth];
if (num < 0) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Incompatible Mat" userInfo:nil];
}
return num * _channels;
}
@end

View File

@ -0,0 +1,62 @@
//
// MatOfInt4.h
//
// Created by Giles Payne on 2019/12/27.
//
#pragma once
#import "Mat.h"
NS_ASSUME_NONNULL_BEGIN
/**
* Mat representation of an array of vectors of four ints
*/
CV_EXPORTS @interface MatOfInt4 : Mat
#pragma mark - Constructors
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat;
#endif
/**
* Create MatOfInt4 from Mat object
* @param mat Mat object from which to create MatOfInt4
*/
- (instancetype)initWithMat:(Mat*)mat;
/**
* Create MatOfInt4 from array
* @param array Array from which to create MatOfInt4
*/
- (instancetype)initWithArray:(NSArray<NSNumber*>*)array;
#pragma mark - Methods
/**
* Allocate specified number of elements
* @param elemNumber Number of elements
*/
- (void)alloc:(int)elemNumber;
/**
* Populate Mat with elements of an array
* @param array Array with which to populate the Mat
*/
- (void)fromArray:(NSArray<NSNumber*>*)array;
/**
* Output Mat elements as an array
*/
- (NSArray<NSNumber*>*)toArray;
/**
* Total number of values in Mat
*/
- (int)length;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,69 @@
//
// MatOfInt4.mm
//
// Created by Giles Payne on 2019/12/27.
//
#import "MatOfInt4.h"
#import "Range.h"
#import "CvType.h"
#import "ArrayUtil.h"
@implementation MatOfInt4
static const int _depth = CV_32S;
static const int _channels = 4;
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat {
self = [super initWithNativeMat:nativeMat];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
#endif
- (instancetype)initWithMat:(Mat*)mat {
self = [super initWithMat:mat rowRange:[Range all]];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
- (instancetype)initWithArray:(NSArray<NSNumber*>*)array {
self = [super init];
if (self) {
[self fromArray:array];
}
return self;
}
- (void)alloc:(int)elemNumber {
if (elemNumber>0) {
[super create:elemNumber cols:1 type:[CvType makeType:_depth channels:_channels]];
}
}
- (void)fromArray:(NSArray<NSNumber*>*)array {
[self alloc:(int)array.count / _channels];
[self put:0 col:0 data:array];
}
- (NSArray<NSNumber*>*)toArray {
int length = [self length];
NSMutableArray<NSNumber*>* data = createArrayWithSize(length, @0.0);
[self get:0 col:0 data:data];
return data;
}
- (int)length {
int num = [self checkVector:_channels depth:_depth];
if (num < 0) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Incompatible Mat" userInfo:nil];
}
return num * _channels;
}
@end

View File

@ -0,0 +1,64 @@
//
// MatOfKeyPoint.h
//
// Created by Giles Payne on 2019/12/27.
//
#pragma once
#import "Mat.h"
@class KeyPoint;
NS_ASSUME_NONNULL_BEGIN
/**
* Mat representation of an array of KeyPoint objects
*/
CV_EXPORTS @interface MatOfKeyPoint : Mat
#pragma mark - Constructors
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat;
#endif
/**
* Create MatOfKeyPoint from Mat object
* @param mat Mat object from which to create MatOfKeyPoint
*/
- (instancetype)initWithMat:(Mat*)mat;
/**
* Create MatOfKeyPoint from array
* @param array Array from which to create MatOfKeyPoint
*/
- (instancetype)initWithArray:(NSArray<KeyPoint*>*)array;
#pragma mark - Methods
/**
* Allocate specified number of elements
* @param elemNumber Number of elements
*/
- (void)alloc:(int)elemNumber;
/**
* Populate Mat with elements of an array
* @param array Array with which to populate the Mat
*/
- (void)fromArray:(NSArray<KeyPoint*>*)array;
/**
* Output Mat elements as an array of KeyPoint objects
*/
- (NSArray<KeyPoint*>*)toArray;
/**
* Total number of values in Mat
*/
- (int)length;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,87 @@
//
// MatOfKeyPoint.m
//
// Created by Giles Payne on 2019/12/27.
//
#import "MatOfKeyPoint.h"
#import "Range.h"
#import "Point2f.h"
#import "KeyPoint.h"
#import "CvType.h"
#import "ArrayUtil.h"
@implementation MatOfKeyPoint
static const int _depth = CV_32F;
static const int _channels = 7;
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat {
self = [super initWithNativeMat:nativeMat];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
#endif
- (instancetype)initWithMat:(Mat*)mat {
self = [super initWithMat:mat rowRange:[Range all]];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
- (instancetype)initWithArray:(NSArray<KeyPoint*>*)array {
self = [super init];
if (self) {
[self fromArray:array];
}
return self;
}
- (void)alloc:(int)elemNumber {
if (elemNumber>0) {
[super create:elemNumber cols:1 type:[CvType makeType:_depth channels:_channels]];
}
}
- (void)fromArray:(NSArray<KeyPoint*>*)array {
NSMutableArray<NSNumber*>* data = [[NSMutableArray alloc] initWithCapacity:array.count * _channels];
for (int index = 0; index < (int)array.count; index++) {
data[_channels * index] = [NSNumber numberWithFloat:array[index].pt.x];
data[_channels * index + 1] = [NSNumber numberWithFloat:array[index].pt.y];
data[_channels * index + 2] = [NSNumber numberWithFloat:array[index].size];
data[_channels * index + 3] = [NSNumber numberWithFloat:array[index].angle];
data[_channels * index + 4] = [NSNumber numberWithFloat:array[index].response];
data[_channels * index + 5] = [NSNumber numberWithFloat:array[index].octave];
data[_channels * index + 6] = [NSNumber numberWithFloat:array[index].classId];
}
[self alloc:(int)array.count];
[self put:0 col:0 data:data];
}
- (NSArray<KeyPoint*>*)toArray {
int length = [self length] / _channels;
NSMutableArray<KeyPoint*>* ret = createArrayWithSize(length, [KeyPoint new]);
if (length > 0) {
NSMutableArray<NSNumber*>* data = createArrayWithSize([self length], @0.0);
[self get:0 col:0 data:data];
for (int index = 0; index < length; index++) {
ret[index] = [[KeyPoint alloc] initWithX:data[index * _channels].floatValue y:data[index * _channels + 1].floatValue size:data[index * _channels + 2].floatValue angle:data[index * _channels + 3].floatValue response:data[index * _channels + 4].floatValue octave:data[index * _channels + 5].intValue classId:data[index * _channels + 6].intValue];
}
}
return ret;
}
- (int)length {
int num = [self checkVector:_channels depth:_depth];
if (num < 0) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Incompatible Mat" userInfo:nil];
}
return num * _channels;
}
@end

View File

@ -0,0 +1,64 @@
//
// MatOfPoint2f.h
//
// Created by Giles Payne on 2019/12/27.
//
#pragma once
#import "Mat.h"
NS_ASSUME_NONNULL_BEGIN
@class Point2f;
/**
* Mat representation of an array of Point2f objects
*/
CV_EXPORTS @interface MatOfPoint2f : Mat
#pragma mark - Constructors
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat;
#endif
/**
* Create MatOfPoint2f from Mat object
* @param mat Mat object from which to create MatOfPoint2f
*/
- (instancetype)initWithMat:(Mat*)mat;
/**
* Create MatOfPoint2f from array
* @param array Array from which to create MatOfPoint2f
*/
- (instancetype)initWithArray:(NSArray<Point2f*>*)array;
#pragma mark - Methods
/**
* Allocate specified number of elements
* @param elemNumber Number of elements
*/
- (void)alloc:(int)elemNumber;
/**
* Populate Mat with elements of an array
* @param array Array with which to populate the Mat
*/
- (void)fromArray:(NSArray<Point2f*>*)array;
/**
* Output Mat elements as an array of Point2f objects
*/
- (NSArray<Point2f*>*)toArray;
/**
* Total number of values in Mat
*/
- (int)length;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,81 @@
//
// MatOfPoint2f.mm
//
// Created by Giles Payne on 2019/12/27.
//
#import "MatOfPoint2f.h"
#import "Range.h"
#import "Point2f.h"
#import "CvType.h"
#import "ArrayUtil.h"
@implementation MatOfPoint2f
static const int _depth = CV_32F;
static const int _channels = 2;
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat {
self = [super initWithNativeMat:nativeMat];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
#endif
- (instancetype)initWithMat:(Mat*)mat {
self = [super initWithMat:mat rowRange:[Range all]];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
- (instancetype)initWithArray:(NSArray<Point2f*>*)array {
self = [super init];
if (self) {
[self fromArray:array];
}
return self;
}
- (void)alloc:(int)elemNumber {
if (elemNumber>0) {
[super create:elemNumber cols:1 type:[CvType makeType:_depth channels:_channels]];
}
}
- (void)fromArray:(NSArray<Point2f*>*)array {
NSMutableArray<NSNumber*>* data = [[NSMutableArray alloc] initWithCapacity:array.count * _channels];
for (int index = 0; index < (int)array.count; index++) {
data[_channels * index] = [NSNumber numberWithFloat:array[index].x];
data[_channels * index + 1] = [NSNumber numberWithFloat:array[index].y];
}
[self alloc:(int)array.count];
[self put:0 col:0 data:data];
}
- (NSArray<Point2f*>*)toArray {
int length = [self length] / _channels;
NSMutableArray<Point2f*>* ret = createArrayWithSize(length, [Point2f new]);
if (length > 0) {
NSMutableArray<NSNumber*>* data = createArrayWithSize([self length], @0.0);
[self get:0 col:0 data:data];
for (int index = 0; index < length; index++) {
ret[index] = [[Point2f alloc] initWithX:data[index * _channels].floatValue y:data[index * _channels + 1].floatValue];
}
}
return ret;
}
- (int)length {
int num = [self checkVector:_channels depth:_depth];
if (num < 0) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Incompatible Mat" userInfo:nil];
}
return num * _channels;
}
@end

View File

@ -0,0 +1,65 @@
//
// MatOfPoint2i.h
//
// Created by Giles Payne on 2019/12/27.
//
#pragma once
#import "Mat.h"
@class Point2i;
NS_ASSUME_NONNULL_BEGIN
/**
* Mat representation of an array of Point objects
*/
NS_SWIFT_NAME(MatOfPoint)
CV_EXPORTS @interface MatOfPoint2i : Mat
#pragma mark - Constructors
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat;
#endif
/**
* Create MatOfPoint from Mat object
* @param mat Mat object from which to create MatOfPoint
*/
- (instancetype)initWithMat:(Mat*)mat;
/**
* Create MatOfPoint from array
* @param array Array from which to create MatOfPoint
*/
- (instancetype)initWithArray:(NSArray<Point2i*>*)array;
#pragma mark - Methods
/**
* Allocate specified number of elements
* @param elemNumber Number of elements
*/
- (void)alloc:(int)elemNumber;
/**
* Populate Mat with elements of an array
* @param array Array with which to populate the Mat
*/
- (void)fromArray:(NSArray<Point2i*>*)array;
/**
* Output Mat elements as an array of Point objects
*/
- (NSArray<Point2i*>*)toArray;
/**
* Total number of values in Mat
*/
- (int)length;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,81 @@
//
// MatOfPoint2i.mm
//
// Created by Giles Payne on 2019/12/27.
//
#import "MatOfPoint2i.h"
#import "Range.h"
#import "Point2i.h"
#import "CvType.h"
#import "ArrayUtil.h"
@implementation MatOfPoint2i
static const int _depth = CV_32S;
static const int _channels = 2;
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat {
self = [super initWithNativeMat:nativeMat];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
#endif
- (instancetype)initWithMat:(Mat*)mat {
self = [super initWithMat:mat rowRange:[Range all]];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
- (instancetype)initWithArray:(NSArray<Point2i*>*)array {
self = [super init];
if (self) {
[self fromArray:array];
}
return self;
}
- (void)alloc:(int)elemNumber {
if (elemNumber>0) {
[super create:elemNumber cols:1 type:[CvType makeType:_depth channels:_channels]];
}
}
- (void)fromArray:(NSArray<Point2i*>*)array {
NSMutableArray<NSNumber*>* data = [[NSMutableArray alloc] initWithCapacity:array.count * _channels];
for (int index = 0; index < (int)array.count; index++) {
data[_channels * index] = [NSNumber numberWithInt:array[index].x];
data[_channels * index + 1] = [NSNumber numberWithInt:array[index].y];
}
[self alloc:(int)array.count];
[self put:0 col:0 data:data];
}
- (NSArray<Point2i*>*)toArray {
int length = [self length] / _channels;
NSMutableArray<Point2i*>* ret = createArrayWithSize(length, [Point2i new]);
if (length > 0) {
NSMutableArray<NSNumber*>* data = createArrayWithSize([self length], @0.0);
[self get:0 col:0 data:data];
for (int index = 0; index < length; index++) {
ret[index] = [[Point2i alloc] initWithX:data[index * _channels].intValue y:data[index * _channels + 1].intValue];
}
}
return ret;
}
- (int)length {
int num = [self checkVector:_channels depth:_depth];
if (num < 0) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Incompatible Mat" userInfo:nil];
}
return num * _channels;
}
@end

View File

@ -0,0 +1,64 @@
//
// MatOfPoint3.h
//
// Created by Giles Payne on 2019/12/27.
//
#pragma once
#import "Mat.h"
@class Point3i;
NS_ASSUME_NONNULL_BEGIN
/**
* Mat representation of an array of Point3i objects
*/
CV_EXPORTS @interface MatOfPoint3 : Mat
#pragma mark - Constructors
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat;
#endif
/**
* Create MatOfPoint3 from Mat object
* @param mat Mat object from which to create MatOfPoint3
*/
- (instancetype)initWithMat:(Mat*)mat;
/**
* Create MatOfPoint3 from array
* @param array Array from which to create MatOfPoint3
*/
- (instancetype)initWithArray:(NSArray<Point3i*>*)array;
#pragma mark - Methods
/**
* Allocate specified number of elements
* @param elemNumber Number of elements
*/
- (void)alloc:(int)elemNumber;
/**
* Populate Mat with elements of an array
* @param array Array with which to populate the Mat
*/
- (void)fromArray:(NSArray<Point3i*>*)array;
/**
* Output Mat elements as an array of Point3i objects
*/
- (NSArray<Point3i*>*)toArray;
/**
* Total number of values in Mat
*/
- (int)length;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,82 @@
//
// MatOfPoint3.mm
//
// Created by Giles Payne on 2019/12/27.
//
#import "MatOfPoint3.h"
#import "Range.h"
#import "Point3i.h"
#import "CvType.h"
#import "ArrayUtil.h"
@implementation MatOfPoint3
static const int _depth = CV_32S;
static const int _channels = 3;
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat {
self = [super initWithNativeMat:nativeMat];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
#endif
- (instancetype)initWithMat:(Mat*)mat {
self = [super initWithMat:mat rowRange:[Range all]];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
- (instancetype)initWithArray:(NSArray<Point3i*>*)array {
self = [super init];
if (self) {
[self fromArray:array];
}
return self;
}
- (void)alloc:(int)elemNumber {
if (elemNumber>0) {
[super create:elemNumber cols:1 type:[CvType makeType:_depth channels:_channels]];
}
}
- (void)fromArray:(NSArray<Point3i*>*)array {
NSMutableArray<NSNumber*>* data = [[NSMutableArray alloc] initWithCapacity:array.count * _channels];
for (int index = 0; index < (int)array.count; index++) {
data[_channels * index] = [NSNumber numberWithInt:array[index].x];
data[_channels * index + 1] = [NSNumber numberWithInt:array[index].y];
data[_channels * index + 2] = [NSNumber numberWithInt:array[index].z];
}
[self alloc:(int)array.count];
[self put:0 col:0 data:data];
}
- (NSArray<Point3i*>*)toArray {
int length = [self length] / _channels;
NSMutableArray<Point3i*>* ret = createArrayWithSize(length, [Point3i new]);
if (length > 0) {
NSMutableArray<NSNumber*>* data = createArrayWithSize([self length], @0.0);
[self get:0 col:0 data:data];
for (int index = 0; index < length; index++) {
ret[index] = [[Point3i alloc] initWithX:data[index * _channels].intValue y:data[index * _channels + 1].intValue z:data[index * _channels + 2].intValue];
}
}
return ret;
}
- (int)length {
int num = [self checkVector:_channels depth:_depth];
if (num < 0) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Incompatible Mat" userInfo:nil];
}
return num * _channels;
}
@end

View File

@ -0,0 +1,64 @@
//
// MatOfPoint3f.h
//
// Created by Giles Payne on 2019/12/27.
//
#pragma once
#import "Mat.h"
@class Point3f;
NS_ASSUME_NONNULL_BEGIN
/**
* Mat representation of an array of Point3f objects
*/
CV_EXPORTS @interface MatOfPoint3f : Mat
#pragma mark - Constructors
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat;
#endif
/**
* Create MatOfPoint3f from Mat object
* @param mat Mat object from which to create MatOfPoint3f
*/
- (instancetype)initWithMat:(Mat*)mat;
/**
* Create MatOfPoint3f from array
* @param array Array from which to create MatOfPoint3f
*/
- (instancetype)initWithArray:(NSArray<Point3f*>*)array;
#pragma mark - Methods
/**
* Allocate specified number of elements
* @param elemNumber Number of elements
*/
- (void)alloc:(int)elemNumber;
/**
* Populate Mat with elements of an array
* @param array Array with which to populate the Mat
*/
- (void)fromArray:(NSArray<Point3f*>*)array;
/**
* Output Mat elements as an array of Point3f objects
*/
- (NSArray<Point3f*>*)toArray;
/**
* Total number of values in Mat
*/
- (int)length;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,82 @@
//
// MatOfPoint3f.mm
//
// Created by Giles Payne on 2019/12/27.
//
#import "MatOfPoint3f.h"
#import "Range.h"
#import "Point3f.h"
#import "CvType.h"
#import "ArrayUtil.h"
@implementation MatOfPoint3f
static const int _depth = CV_32F;
static const int _channels = 3;
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat {
self = [super initWithNativeMat:nativeMat];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
#endif
- (instancetype)initWithMat:(Mat*)mat {
self = [super initWithMat:mat rowRange:[Range all]];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
- (instancetype)initWithArray:(NSArray<Point3f*>*)array {
self = [super init];
if (self) {
[self fromArray:array];
}
return self;
}
- (void)alloc:(int)elemNumber {
if (elemNumber>0) {
[super create:elemNumber cols:1 type:[CvType makeType:_depth channels:_channels]];
}
}
- (void)fromArray:(NSArray<Point3f*>*)array {
NSMutableArray<NSNumber*>* data = [[NSMutableArray alloc] initWithCapacity:array.count * _channels];
for (int index = 0; index < (int)array.count; index++) {
data[_channels * index] = [NSNumber numberWithFloat:array[index].x];
data[_channels * index + 1] = [NSNumber numberWithFloat:array[index].y];
data[_channels * index + 2] = [NSNumber numberWithFloat:array[index].z];
}
[self alloc:(int)array.count];
[self put:0 col:0 data:data];
}
- (NSArray<Point3f*>*)toArray {
int length = [self length] / _channels;
NSMutableArray<Point3f*>* ret = createArrayWithSize(length, [Point3f new]);
if (length > 0) {
NSMutableArray<NSNumber*>* data = createArrayWithSize([self length], @0.0);
[self get:0 col:0 data:data];
for (int index = 0; index < length; index++) {
ret[index] = [[Point3f alloc] initWithX:data[index * _channels].floatValue y:data[index * _channels + 1].floatValue z:data[index * _channels + 2].floatValue];
}
}
return ret;
}
- (int)length {
int num = [self checkVector:_channels depth:_depth];
if (num < 0) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Incompatible Mat" userInfo:nil];
}
return num * _channels;
}
@end

View File

@ -0,0 +1,65 @@
//
// MatOfRect2d.h
//
// Created by Giles Payne on 2019/12/27.
//
#pragma once
#import "Mat.h"
@class Rect2d;
NS_ASSUME_NONNULL_BEGIN
/**
* Mat representation of an array of Rect2d objects
*/
CV_EXPORTS @interface MatOfRect2d : Mat
#pragma mark - Constructors
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat;
+ (instancetype)fromNative:(cv::Mat*)nativeMat;
#endif
/**
* Create MatOfRect2d from Mat object
* @param mat Mat object from which to create MatOfRect2d
*/
- (instancetype)initWithMat:(Mat*)mat;
/**
* Create MatOfRect2d from array
* @param array Array from which to create MatOfRect2d
*/
- (instancetype)initWithArray:(NSArray<Rect2d*>*)array;
#pragma mark - Methods
/**
* Allocate specified number of elements
* @param elemNumber Number of elements
*/
- (void)alloc:(int)elemNumber;
/**
* Populate Mat with elements of an array
* @param array Array with which to populate the Mat
*/
- (void)fromArray:(NSArray<Rect2d*>*)array;
/**
* Output Mat elements as an array of Rect2d objects
*/
- (NSArray<Rect2d*>*)toArray;
/**
* Total number of values in Mat
*/
- (int)length;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,88 @@
//
// MatOfRect2d.mm
//
// Created by Giles Payne on 2019/12/27.
//
#import "MatOfRect2d.h"
#import "Range.h"
#import "Rect2d.h"
#import "CvType.h"
#import "ArrayUtil.h"
@implementation MatOfRect2d
static const int _depth = CV_64F;
static const int _channels = 4;
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat {
self = [super initWithNativeMat:nativeMat];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
+ (instancetype)fromNative:(cv::Mat*)nativeMat {
return [[MatOfRect2d alloc] initWithNativeMat:nativeMat];
}
#endif
- (instancetype)initWithMat:(Mat*)mat {
self = [super initWithMat:mat rowRange:[Range all]];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
- (instancetype)initWithArray:(NSArray<Rect2d*>*)array {
self = [super init];
if (self) {
[self fromArray:array];
}
return self;
}
- (void)alloc:(int)elemNumber {
if (elemNumber>0) {
[super create:elemNumber cols:1 type:[CvType makeType:_depth channels:_channels]];
}
}
- (void)fromArray:(NSArray<Rect2d*>*)array {
NSMutableArray<NSNumber*>* data = [[NSMutableArray alloc] initWithCapacity:array.count * _channels];
for (int index = 0; index < (int)array.count; index++) {
data[_channels * index] = [NSNumber numberWithDouble:array[index].x];
data[_channels * index + 1] = [NSNumber numberWithDouble:array[index].y];
data[_channels * index + 2] = [NSNumber numberWithDouble:array[index].width];
data[_channels * index + 3] = [NSNumber numberWithDouble:array[index].height];
}
[self alloc:(int)array.count];
[self put:0 col:0 data:data];
}
- (NSArray<Rect2d*>*)toArray {
int length = [self length] / _channels;
NSMutableArray<Rect2d*>* ret = createArrayWithSize(length, [Rect2d new]);
if (length > 0) {
NSMutableArray<NSNumber*>* data = createArrayWithSize([self length], @0.0);
[self get:0 col:0 data:data];
for (int index = 0; index < length; index++) {
ret[index] = [[Rect2d alloc] initWithX:data[index * _channels].doubleValue y:data[index * _channels + 1].doubleValue width:data[index * _channels + 2].doubleValue height:data[index * _channels + 3].doubleValue];
}
}
return ret;
}
- (int)length {
int num = [self checkVector:_channels depth:_depth];
if (num < 0) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Incompatible Mat" userInfo:nil];
}
return num * _channels;
}
@end

View File

@ -0,0 +1,65 @@
//
// MatOfRect2i.h
//
// Created by Giles Payne on 2019/12/27.
//
#pragma once
#import "Mat.h"
@class Rect2i;
NS_ASSUME_NONNULL_BEGIN
/**
* Mat representation of an array of Rect objects
*/
NS_SWIFT_NAME(MatOfRect)
CV_EXPORTS @interface MatOfRect2i : Mat
#pragma mark - Constructors
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat;
#endif
/**
* Create MatOfRect from Mat object
* @param mat Mat object from which to create MatOfRect
*/
- (instancetype)initWithMat:(Mat*)mat;
/**
* Create MatOfRect from array
* @param array Array from which to create MatOfRect
*/
- (instancetype)initWithArray:(NSArray<Rect2i*>*)array;
#pragma mark - Methods
/**
* Allocate specified number of elements
* @param elemNumber Number of elements
*/
- (void)alloc:(int)elemNumber;
/**
* Populate Mat with elements of an array
* @param array Array with which to populate the Mat
*/
- (void)fromArray:(NSArray<Rect2i*>*)array;
/**
* Output Mat elements as an array of Rect objects
*/
- (NSArray<Rect2i*>*)toArray;
/**
* Total number of values in Mat
*/
- (int)length;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,83 @@
//
// MatOfRect2i.m
//
// Created by Giles Payne on 2019/12/27.
//
#import "MatOfRect2i.h"
#import "Range.h"
#import "Rect2i.h"
#import "CvType.h"
#import "ArrayUtil.h"
@implementation MatOfRect2i
static const int _depth = CV_32S;
static const int _channels = 4;
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat {
self = [super initWithNativeMat:nativeMat];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
#endif
- (instancetype)initWithMat:(Mat*)mat {
self = [super initWithMat:mat rowRange:[Range all]];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
- (instancetype)initWithArray:(NSArray<Rect2i*>*)array {
self = [super init];
if (self) {
[self fromArray:array];
}
return self;
}
- (void)alloc:(int)elemNumber {
if (elemNumber>0) {
[super create:elemNumber cols:1 type:[CvType makeType:_depth channels:_channels]];
}
}
- (void)fromArray:(NSArray<Rect2i*>*)array {
NSMutableArray<NSNumber*>* data = [[NSMutableArray alloc] initWithCapacity:array.count * _channels];
for (int index = 0; index < (int)array.count; index++) {
data[_channels * index] = [NSNumber numberWithInt:array[index].x];
data[_channels * index + 1] = [NSNumber numberWithInt:array[index].y];
data[_channels * index + 2] = [NSNumber numberWithInt:array[index].width];
data[_channels * index + 3] = [NSNumber numberWithInt:array[index].height];
}
[self alloc:(int)array.count];
[self put:0 col:0 data:data];
}
- (NSArray<Rect2i*>*)toArray {
int length = [self length] / _channels;
NSMutableArray<Rect2i*>* ret = createArrayWithSize(length, [Rect2i new]);
if (length > 0) {
NSMutableArray<NSNumber*>* data = createArrayWithSize([self length], @0.0);
[self get:0 col:0 data:data];
for (int index = 0; index < length; index++) {
ret[index] = [[Rect2i alloc] initWithX:data[index * _channels].intValue y:data[index * _channels + 1].intValue width:data[index * _channels + 2].intValue height:data[index * _channels + 3].intValue];
}
}
return ret;
}
- (int)length {
int num = [self checkVector:_channels depth:_depth];
if (num < 0) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Incompatible Mat" userInfo:nil];
}
return num * _channels;
}
@end

View File

@ -0,0 +1,64 @@
//
// MatOfRotatedRect.h
//
// Created by Giles Payne on 2019/12/27.
//
#pragma once
#import "Mat.h"
@class RotatedRect;
NS_ASSUME_NONNULL_BEGIN
/**
* Mat representation of an array of RotatedRect objects
*/
CV_EXPORTS @interface MatOfRotatedRect : Mat
#pragma mark - Constructors
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat;
#endif
/**
* Create MatOfRotatedRect from Mat object
* @param mat Mat object from which to create MatOfRotatedRect
*/
- (instancetype)initWithMat:(Mat*)mat;
/**
* Create MatOfRotatedRect from array
* @param array Array from which to create MatOfRotatedRect
*/
- (instancetype)initWithArray:(NSArray<RotatedRect*>*)array;
#pragma mark - Methods
/**
* Allocate specified number of elements
* @param elemNumber Number of elements
*/
- (void)alloc:(int)elemNumber;
/**
* Populate Mat with elements of an array
* @param array Array with which to populate the Mat
*/
- (void)fromArray:(NSArray<RotatedRect*>*)array;
/**
* Output Mat elements as an array of RotatedRect objects
*/
- (NSArray<RotatedRect*>*)toArray;
/**
* Total number of values in Mat
*/
- (int)length;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,87 @@
//
// MatOfRotatedRect.mm
//
// Created by Giles Payne on 2019/12/27.
//
#import "MatOfRotatedRect.h"
#import "Range.h"
#import "RotatedRect.h"
#import "Point2f.h"
#import "Size2f.h"
#import "CvType.h"
#import "ArrayUtil.h"
@implementation MatOfRotatedRect
static const int _depth = CV_32F;
static const int _channels = 5;
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat {
self = [super initWithNativeMat:nativeMat];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
#endif
- (instancetype)initWithMat:(Mat*)mat {
self = [super initWithMat:mat rowRange:[Range all]];
if (self && ![self empty] && [self checkVector:_channels depth:_depth] < 0) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Incompatible Mat" userInfo:nil];
}
return self;
}
- (instancetype)initWithArray:(NSArray<RotatedRect*>*)array {
self = [super init];
if (self) {
[self fromArray:array];
}
return self;
}
- (void)alloc:(int)elemNumber {
if (elemNumber>0) {
[super create:elemNumber cols:1 type:[CvType makeType:_depth channels:_channels]];
}
}
- (void)fromArray:(NSArray<RotatedRect*>*)array {
NSMutableArray<NSNumber*>* data = [[NSMutableArray alloc] initWithCapacity:array.count * _channels];
for (int index = 0; index < (int)array.count; index++) {
data[_channels * index] = [NSNumber numberWithFloat:array[index].center.x];
data[_channels * index + 1] = [NSNumber numberWithFloat:array[index].center.y];
data[_channels * index + 2] = [NSNumber numberWithFloat:array[index].size.width];
data[_channels * index + 3] = [NSNumber numberWithFloat:array[index].size.height];
data[_channels * index + 4] = [NSNumber numberWithFloat:array[index].angle];
}
[self alloc:(int)array.count];
[self put:0 col:0 data:data];
}
- (NSArray<RotatedRect*>*)toArray {
int length = [self length] / _channels;
NSMutableArray<RotatedRect*>* ret = createArrayWithSize(length, [RotatedRect new]);
if (length > 0) {
NSMutableArray<NSNumber*>* data = createArrayWithSize([self length], @0.0);
[self get:0 col:0 data:data];
for (int index = 0; index < length; index++) {
ret[index] = [[RotatedRect alloc] initWithCenter:[[Point2f alloc] initWithX:data[index * _channels].floatValue y:data[index * _channels + 1].floatValue] size:[[Size2f alloc] initWithWidth:data[index * _channels + 2].floatValue height:data[index * _channels + 3].floatValue] angle:data[index * _channels + 4].floatValue];
}
}
return ret;
}
- (int)length {
int num = [self checkVector:_channels depth:_depth];
if (num < 0) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Incompatible Mat" userInfo:nil];
}
return num * _channels;
}
@end

View File

@ -0,0 +1,40 @@
//
// MinMaxLocResult.h
//
// Created by Giles Payne on 2019/12/28.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
#import <Foundation/Foundation.h>
@class Point2i;
NS_ASSUME_NONNULL_BEGIN
/**
* Result of operation to determine global minimum and maximum of an array
*/
CV_EXPORTS @interface MinMaxLocResult : NSObject
#pragma mark - Properties
@property double minVal;
@property double maxVal;
@property Point2i* minLoc;
@property Point2i* maxLoc;
#pragma mark - Constructors
- (instancetype)init;
- (instancetype)initWithMinval:(double)minVal maxVal:(double)maxVal minLoc:(Point2i*)minLoc maxLoc:(Point2i*)maxLoc;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,27 @@
//
// MinMaxLocResult.m
//
// Created by Giles Payne on 2019/12/28.
//
#import "MinMaxLocResult.h"
#import "Point2i.h"
@implementation MinMaxLocResult
- (instancetype)init {
return [self initWithMinval:0 maxVal:0 minLoc:[Point2i new] maxLoc:[Point2i new]];
}
- (instancetype)initWithMinval:(double)minVal maxVal:(double)maxVal minLoc:(Point2i*)minLoc maxLoc:(Point2i*)maxLoc {
self = [super init];
if (self) {
self.minVal = minVal;
self.maxVal = maxVal;
self.minLoc = minLoc;
self.maxLoc = maxLoc;
}
return self;
}
@end

View File

@ -0,0 +1,89 @@
//
// Point2d.h
//
// Created by Giles Payne on 2019/10/09.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
#import <Foundation/Foundation.h>
@class Rect2d;
NS_ASSUME_NONNULL_BEGIN
/**
* Represents a two dimensional point the coordinate values of which are of type `double`
*/
CV_EXPORTS @interface Point2d : NSObject
# pragma mark - Properties
@property double x;
@property double y;
#ifdef __cplusplus
@property(readonly) cv::Point2d& nativeRef;
#endif
# pragma mark - Constructors
- (instancetype)init;
- (instancetype)initWithX:(double)x y:(double)y;
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#ifdef __cplusplus
+ (instancetype)fromNative:(cv::Point2d&)point;
- (void)update:(cv::Point2d&)point;
#endif
# pragma mark - Methods
/**
* Calculate the dot product of this point and another point
* @param point The other point
*/
- (double)dot:(Point2d*)point;
/**
* Determine if the point lies with a specified rectangle
* @param rect The rectangle
*/
- (BOOL)inside:(Rect2d*)rect;
/**
* Set the point coordinates from the values of an array
* @param vals The array of values from which to set the coordinates
*/
- (void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
# pragma mark - Common Methods
/**
* Clone object
*/
- (Point2d*)clone;
/**
* Compare for equality
* @param other Object to compare
*/
- (BOOL)isEqual:(nullable id)other;
/**
* Calculate hash value for this object
*/
- (NSUInteger)hash;
/**
* Returns a string that describes the contents of the object
*/
- (NSString*)description;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,108 @@
//
// Point2d.m
//
// Created by Giles Payne on 2019/10/09.
//
#import "Point2d.h"
#import "Rect2d.h"
@implementation Point2d {
cv::Point2d native;
}
- (double)x {
return native.x;
}
- (void)setX:(double)val {
native.x = val;
}
- (double)y {
return native.y;
}
- (void)setY:(double)val {
native.y = val;
}
- (cv::Point2d&)nativeRef {
return native;
}
- (instancetype)init {
return [self initWithX:0 y:0];
}
- (instancetype)initWithX:(double)x y:(double)y {
self = [super init];
if (self) {
self.x = x;
self.y = y;
}
return self;
}
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
self = [super init];
if (self) {
[self set:vals];
}
return self;
}
+ (instancetype)fromNative:(cv::Point2d&)point {
return [[Point2d alloc] initWithX:point.x y:point.y];
}
- (void)update:(cv::Point2d&)point {
self.x = point.x;
self.y = point.y;
}
- (Point2d*) clone {
return [[Point2d alloc] initWithX:self.x y:self.y];
}
- (double)dot:(Point2d*)point {
return self.x * point.x + self.y * point.y;
}
- (void)set:(NSArray<NSNumber*>*)vals {
self.x = (vals != nil && vals.count > 0) ? vals[0].doubleValue : 0;
self.y = (vals != nil && vals.count > 1) ? vals[1].doubleValue : 0;
}
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
} else if (![other isKindOfClass:[Point2d class]]) {
return NO;
} else {
Point2d* point = (Point2d*)other;
return self.x == point.x && self.y == point.y;
}
}
- (BOOL)inside:(Rect2d*)rect {
return [rect contains:self];
}
#define DOUBLE_TO_BITS(x) ((Cv64suf){ .f = x }).i
- (NSUInteger)hash {
int prime = 31;
uint32_t result = 1;
int64_t temp = DOUBLE_TO_BITS(self.x);
result = prime * result + (int32_t) (temp ^ (temp >> 32));
temp = DOUBLE_TO_BITS(self.y);
result = prime * result + (int32_t) (temp ^ (temp >> 32));
return result;
}
- (NSString *)description {
return [NSString stringWithFormat:@"Point2d {%lf,%lf}", self.x, self.y];
}
@end

View File

@ -0,0 +1,89 @@
//
// Point2f.h
//
// Created by Giles Payne on 2019/10/09.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
#import <Foundation/Foundation.h>
@class Rect2f;
NS_ASSUME_NONNULL_BEGIN
/**
* Represents a two dimensional point the coordinate values of which are of type `float`
*/
CV_EXPORTS @interface Point2f : NSObject
# pragma mark - Properties
@property float x;
@property float y;
#ifdef __cplusplus
@property(readonly) cv::Point2f& nativeRef;
#endif
# pragma mark - Constructors
- (instancetype)init;
- (instancetype)initWithX:(float)x y:(float)y;
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#ifdef __cplusplus
+ (instancetype)fromNative:(cv::Point2f&)point;
- (void)update:(cv::Point2f&)point;
#endif
# pragma mark - Methods
/**
* Calculate the dot product of this point and another point
* @param point The other point
*/
- (double)dot:(Point2f*)point;
/**
* Determine if the point lies with a specified rectangle
* @param rect The rectangle
*/
- (BOOL)inside:(Rect2f*)rect;
/**
* Set the point coordinates from the values of an array
* @param vals The array of values from which to set the coordinates
*/
- (void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
# pragma mark - Common Methods
/**
* Clone object
*/
- (Point2f*)clone;
/**
* Compare for equality
* @param other Object to compare
*/
- (BOOL)isEqual:(nullable id)other;
/**
* Calculate hash value for this object
*/
- (NSUInteger)hash;
/**
* Returns a string that describes the contents of the object
*/
- (NSString*)description;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,106 @@
//
// Point2f.m
//
// Created by Giles Payne on 2019/10/09.
//
#import "Point2f.h"
#import "Rect2f.h"
@implementation Point2f {
cv::Point2f native;
}
- (float)x {
return native.x;
}
- (void)setX:(float)val {
native.x = val;
}
- (float)y {
return native.y;
}
- (void)setY:(float)val {
native.y = val;
}
- (cv::Point2f&)nativeRef {
return native;
}
- (instancetype)init {
return [self initWithX:0 y:0];
}
- (instancetype)initWithX:(float)x y:(float)y {
self = [super init];
if (self) {
self.x = x;
self.y = y;
}
return self;
}
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
self = [super init];
if (self) {
[self set:vals];
}
return self;
}
+ (instancetype)fromNative:(cv::Point2f&)point {
return [[Point2f alloc] initWithX:point.x y:point.y];
}
- (void)update:(cv::Point2f&)point {
self.x = point.x;
self.y = point.y;
}
- (Point2f*) clone {
return [[Point2f alloc] initWithX:self.x y:self.y];
}
- (double)dot:(Point2f*)point {
return self.x * point.x + self.y * point.y;
}
- (void)set:(NSArray<NSNumber*>*)vals {
self.x = (vals != nil && vals.count > 0) ? vals[0].doubleValue : 0;
self.y = (vals != nil && vals.count > 1) ? vals[1].doubleValue : 0;
}
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
} else if (![other isKindOfClass:[Point2f class]]) {
return NO;
} else {
Point2f* point = (Point2f*)other;
return self.x == point.x && self.y == point.y;
}
}
- (BOOL)inside:(Rect2f *)rect {
return [rect contains:self];
}
#define FLOAT_TO_BITS(x) ((Cv32suf){ .f = x }).i
- (NSUInteger)hash {
int prime = 31;
uint32_t result = 1;
result = prime * result + FLOAT_TO_BITS(self.x);
result = prime * result + FLOAT_TO_BITS(self.x);
return result;
}
- (NSString *)description {
return [NSString stringWithFormat:@"Point2f {%f,%f}", self.x, self.y];
}
@end

View File

@ -0,0 +1,89 @@
//
// Point2i.h
//
// Created by Giles Payne on 2019/10/09.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
#import <Foundation/Foundation.h>
@class Rect2i;
NS_ASSUME_NONNULL_BEGIN
/**
* Represents a two dimensional point the coordinate values of which are of type `int`
*/
CV_EXPORTS @interface Point2i : NSObject
# pragma mark - Properties
@property int x;
@property int y;
#ifdef __cplusplus
@property(readonly) cv::Point2i& nativeRef;
#endif
# pragma mark - Constructors
- (instancetype)init;
- (instancetype)initWithX:(int)x y:(int)y;
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#ifdef __cplusplus
+ (instancetype)fromNative:(cv::Point2i&)point;
- (void)update:(cv::Point2i&)point;
#endif
# pragma mark - Methods
/**
* Calculate the dot product of this point and another point
* @param point The other point
*/
- (double)dot:(Point2i*)point;
/**
* Determine if the point lies with a specified rectangle
* @param rect The rectangle
*/
- (BOOL)inside:(Rect2i*)rect;
/**
* Set the point coordinates from the values of an array
* @param vals The array of values from which to set the coordinates
*/
- (void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
# pragma mark - Common Methods
/**
* Clone object
*/
- (Point2i*)clone;
/**
* Compare for equality
* @param other Object to compare
*/
- (BOOL)isEqual:(nullable id)other;
/**
* Calculate hash value for this object
*/
- (NSUInteger)hash;
/**
* Returns a string that describes the contents of the object
*/
- (NSString*)description;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,105 @@
//
// Point2i.m
//
// Created by Giles Payne on 2019/10/09.
//
#import "Point2i.h"
#import "Rect2i.h"
#import "CVObjcUtil.h"
@implementation Point2i {
cv::Point2i native;
}
- (int)x {
return native.x;
}
- (void)setX:(int)val {
native.x = val;
}
- (int)y {
return native.y;
}
- (void)setY:(int)val {
native.y = val;
}
- (cv::Point2i&)nativeRef {
return native;
}
- (instancetype)init {
return [self initWithX:0 y:0];
}
- (instancetype)initWithX:(int)x y:(int)y {
self = [super init];
if (self) {
self.x = x;
self.y = y;
}
return self;
}
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
self = [super init];
if (self) {
[self set:vals];
}
return self;
}
+ (instancetype)fromNative:(cv::Point2i&)point {
return [[Point2i alloc] initWithX:point.x y:point.y];
}
- (void)update:(cv::Point2i&)point {
self.x = point.x;
self.y = point.y;
}
- (Point2i*) clone {
return [[Point2i alloc] initWithX:self.x y:self.y];
}
- (double)dot:(Point2i*)point {
return self.x * point.x + self.y * point.y;
}
- (void)set:(NSArray<NSNumber*>*)vals {
self.x = (vals != nil && vals.count > 0) ? vals[0].doubleValue : 0;
self.y = (vals != nil && vals.count > 1) ? vals[1].doubleValue : 0;
}
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
} else if (![other isKindOfClass:[Point2i class]]) {
return NO;
} else {
Point2i* point = (Point2i*)other;
return self.x == point.x && self.y == point.y;
}
}
- (BOOL)inside:(Rect2i*)rect {
return [rect contains:self];
}
- (NSUInteger)hash {
int prime = 31;
uint32_t result = 1;
result = prime * result + self.x;
result = prime * result + self.y;
return result;
}
- (NSString *)description {
return [NSString stringWithFormat:@"Point2i {%d,%d}", self.x, self.y];
}
@end

View File

@ -0,0 +1,91 @@
//
// Point3d.h
//
// Created by Giles Payne on 2019/10/09.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
#import <Foundation/Foundation.h>
@class Point2d;
NS_ASSUME_NONNULL_BEGIN
/**
* Represents a three dimensional point the coordinate values of which are of type `double`
*/
CV_EXPORTS @interface Point3d : NSObject
# pragma mark - Properties
@property double x;
@property double y;
@property double z;
#ifdef __cplusplus
@property(readonly) cv::Point3d& nativeRef;
#endif
# pragma mark - Constructors
- (instancetype)init;
- (instancetype)initWithX:(double)x y:(double)y z:(double)z;
- (instancetype)initWithPoint:(Point2d*)point;
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#ifdef __cplusplus
+ (instancetype)fromNative:(cv::Point3d&)point;
- (void)update:(cv::Point3d&)point;
#endif
# pragma mark - Methods
/**
* Calculate the dot product of this point and another point
* @param point The other point
*/
- (double)dot:(Point3d*)point;
/**
* Calculate the cross product of this point and another point
* @param point The other point
*/
- (Point3d*)cross:(Point3d*)point;
/**
* Set the point coordinates from the values of an array
* @param vals The array of values from which to set the coordinates
*/
- (void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
# pragma mark - Common Methods
/**
* Clone object
*/
- (Point3d*)clone;
/**
* Compare for equality
* @param other Object to compare
*/
- (BOOL)isEqual:(nullable id)other;
/**
* Calculate hash value for this object
*/
- (NSUInteger)hash;
/**
* Returns a string that describes the contents of the object
*/
- (NSString *)description;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,125 @@
//
// Point3d.mm
//
// Created by Giles Payne on 2019/10/09.
//
#import "Point3d.h"
#import "Point2d.h"
@implementation Point3d {
cv::Point3d native;
}
- (double)x {
return native.x;
}
- (void)setX:(double)val {
native.x = val;
}
- (double)y {
return native.y;
}
- (void)setY:(double)val {
native.y = val;
}
- (double)z {
return native.z;
}
- (void)setZ:(double)val {
native.z = val;
}
- (cv::Point3d&)nativeRef {
return native;
}
- (instancetype)init {
return [self initWithX:0 y:0 z:0];
}
- (instancetype)initWithX:(double)x y:(double)y z:(double)z {
self = [super init];
if (self) {
self.x = x;
self.y = y;
self.z = z;
}
return self;
}
- (instancetype)initWithPoint:(Point2d*)point {
return [self initWithX:point.x y:point.y z:0];
}
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
self = [super init];
if (self) {
[self set:vals];
}
return self;
}
+ (instancetype)fromNative:(cv::Point3d&)point {
return [[Point3d alloc] initWithX:point.x y:point.y z:point.z];
}
- (void)update:(cv::Point3d&)point {
self.x = point.x;
self.y = point.y;
self.z = point.z;
}
- (void)set:(NSArray<NSNumber*>*)vals {
self.x = (vals != nil && vals.count > 0) ? vals[0].doubleValue : 0.0;
self.y = (vals != nil && vals.count > 1) ? vals[1].doubleValue : 0.0;
self.z = (vals != nil && vals.count > 2) ? vals[2].doubleValue : 0.0;
}
- (Point3d*) clone {
return [[Point3d alloc] initWithX:self.x y:self.y z:self.z];
}
- (double)dot:(Point3d*)point {
return self.x * point.x + self.y * point.y + self.z * point.z;
}
- (Point3d*)cross:(Point3d*)point {
return [[Point3d alloc] initWithX:(self.y * point.z - self.z * point.y) y:(self.z * point.x - self.x * point.z) z:(self.x * point.y - self.y * point.x)];
}
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
} else if (![other isKindOfClass:[Point3d class]]) {
return NO;
} else {
Point3d* point = (Point3d*)other;
return self.x == point.x && self.y == point.y && self.z == point.z;
}
}
#define DOUBLE_TO_BITS(x) ((Cv64suf){ .f = x }).i
- (NSUInteger)hash {
int prime = 31;
uint32_t result = 1;
int64_t temp = DOUBLE_TO_BITS(self.x);
result = prime * result + (int32_t) (temp ^ (temp >> 32));
temp = DOUBLE_TO_BITS(self.y);
result = prime * result + (int32_t) (temp ^ (temp >> 32));
temp = DOUBLE_TO_BITS(self.z);
result = prime * result + (int32_t) (temp ^ (temp >> 32));
return result;
}
- (NSString *)description {
return [NSString stringWithFormat:@"Point3 {%lf,%lf,%lf}", self.x, self.y, self.z];
}
@end

View File

@ -0,0 +1,91 @@
//
// Point3f.h
//
// Created by Giles Payne on 2019/10/09.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
#import <Foundation/Foundation.h>
@class Point2f;
NS_ASSUME_NONNULL_BEGIN
/**
* Represents a three dimensional point the coordinate values of which are of type `float`
*/
CV_EXPORTS @interface Point3f : NSObject
# pragma mark - Properties
@property float x;
@property float y;
@property float z;
#ifdef __cplusplus
@property(readonly) cv::Point3f& nativeRef;
#endif
# pragma mark - Constructors
- (instancetype)init;
- (instancetype)initWithX:(float)x y:(float)y z:(float)z;
- (instancetype)initWithPoint:(Point2f*)point;
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#ifdef __cplusplus
+ (instancetype)fromNative:(cv::Point3f&)point;
- (void)update:(cv::Point3f&)point;
#endif
# pragma mark - Methods
/**
* Calculate the dot product of this point and another point
* @param point The other point
*/
- (double)dot:(Point3f*)point;
/**
* Calculate the cross product of this point and another point
* @param point The other point
*/
- (Point3f*)cross:(Point3f*)point;
/**
* Set the point coordinates from the values of an array
* @param vals The array of values from which to set the coordinates
*/
- (void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
# pragma mark - Common Methods
/**
* Clone object
*/
- (Point3f*)clone;
/**
* Compare for equality
* @param other Object to compare
*/
- (BOOL)isEqual:(nullable id)other;
/**
* Calculate hash value for this object
*/
- (NSUInteger)hash;
/**
* Returns a string that describes the contents of the object
*/
- (NSString *)description;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,122 @@
//
// Point3f.mm
//
// Created by Giles Payne on 2019/10/09.
//
#import "Point3f.h"
#import "Point2f.h"
@implementation Point3f {
cv::Point3f native;
}
- (float)x {
return native.x;
}
- (void)setX:(float)val {
native.x = val;
}
- (float)y {
return native.y;
}
- (void)setY:(float)val {
native.y = val;
}
- (float)z {
return native.z;
}
- (void)setZ:(float)val {
native.z = val;
}
- (cv::Point3f&)nativeRef {
return native;
}
- (instancetype)init {
return [self initWithX:0 y:0 z:0];
}
- (instancetype)initWithX:(float)x y:(float)y z:(float)z {
self = [super init];
if (self) {
self.x = x;
self.y = y;
self.z = z;
}
return self;
}
- (instancetype)initWithPoint:(Point2f*)point {
return [self initWithX:point.x y:point.y z:0];
}
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
self = [super init];
if (self) {
[self set:vals];
}
return self;
}
+ (instancetype)fromNative:(cv::Point3f&)point {
return [[Point3f alloc] initWithX:point.x y:point.y z:point.z];
}
- (void)update:(cv::Point3f&)point {
self.x = point.x;
self.y = point.y;
self.z = point.z;
}
- (void)set:(NSArray<NSNumber*>*)vals {
self.x = (vals != nil && vals.count > 0) ? vals[0].floatValue : 0.0;
self.y = (vals != nil && vals.count > 1) ? vals[1].floatValue : 0.0;
self.z = (vals != nil && vals.count > 2) ? vals[2].floatValue : 0.0;
}
- (Point3f*) clone {
return [[Point3f alloc] initWithX:self.x y:self.y z:self.z];
}
- (double)dot:(Point3f*)point {
return self.x * point.x + self.y * point.y + self.z * point.z;
}
- (Point3f*)cross:(Point3f*)point {
return [[Point3f alloc] initWithX:(self.y * point.z - self.z * point.y) y:(self.z * point.x - self.x * point.z) z:(self.x * point.y - self.y * point.x)];
}
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
} else if (![other isKindOfClass:[Point3f class]]) {
return NO;
} else {
Point3f* point = (Point3f*)other;
return self.x == point.x && self.y == point.y && self.z == point.z;
}
}
#define FLOAT_TO_BITS(x) ((Cv32suf){ .f = x }).i
- (NSUInteger)hash {
int prime = 31;
uint32_t result = 1;
result = prime * result + FLOAT_TO_BITS(self.x);
result = prime * result + FLOAT_TO_BITS(self.y);
result = prime * result + FLOAT_TO_BITS(self.z);
return result;
}
- (NSString *)description {
return [NSString stringWithFormat:@"Point3f {%f,%f,%f}", self.x, self.y, self.z];
}
@end

View File

@ -0,0 +1,91 @@
//
// Point3i.h
//
// Created by Giles Payne on 2019/10/09.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
#import <Foundation/Foundation.h>
@class Point2i;
NS_ASSUME_NONNULL_BEGIN
/**
* Represents a three dimensional point the coordinate values of which are of type `int`
*/
CV_EXPORTS @interface Point3i : NSObject
# pragma mark - Properties
@property int x;
@property int y;
@property int z;
#ifdef __cplusplus
@property(readonly) cv::Point3i& nativeRef;
#endif
# pragma mark - Constructors
- (instancetype)init;
- (instancetype)initWithX:(int)x y:(int)y z:(int)z;
- (instancetype)initWithPoint:(Point2i*)point;
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#ifdef __cplusplus
+ (instancetype)fromNative:(cv::Point3i&)point;
- (void)update:(cv::Point3i&)point;
#endif
# pragma mark - Methods
/**
* Calculate the dot product of this point and another point
* @param point The other point
*/
- (double)dot:(Point3i*)point;
/**
* Calculate the cross product of this point and another point
* @param point The other point
*/
- (Point3i*)cross:(Point3i*)point;
/**
* Set the point coordinates from the values of an array
* @param vals The array of values from which to set the coordinates
*/
- (void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
# pragma mark - Common Methods
/**
* Clone object
*/
- (Point3i*)clone;
/**
* Compare for equality
* @param other Object to compare
*/
- (BOOL)isEqual:(nullable id)other;
/**
* Calculate hash value for this object
*/
- (NSUInteger)hash;
/**
* Returns a string that describes the contents of the object
*/
- (NSString *)description;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,121 @@
//
// Point3i.mm
//
// Created by Giles Payne on 2019/10/09.
//
#import "Point3i.h"
#import "Point2i.h"
#import "CVObjcUtil.h"
@implementation Point3i {
cv::Point3i native;
}
- (int)x {
return native.x;
}
- (void)setX:(int)val {
native.x = val;
}
- (int)y {
return native.y;
}
- (void)setY:(int)val {
native.y = val;
}
- (int)z {
return native.z;
}
- (void)setZ:(int)val {
native.z = val;
}
- (cv::Point3i&)nativeRef {
return native;
}
- (instancetype)init {
return [self initWithX:0 y:0 z:0];
}
- (instancetype)initWithX:(int)x y:(int)y z:(int)z {
self = [super init];
if (self) {
self.x = x;
self.y = y;
self.z = z;
}
return self;
}
- (instancetype)initWithPoint:(Point2i*)point {
return [self initWithX:point.x y:point.y z:0];
}
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
self = [super init];
if (self) {
[self set:vals];
}
return self;
}
+ (instancetype)fromNative:(cv::Point3i&)point {
return [[Point3i alloc] initWithX:point.x y:point.y z:point.z];
}
- (void)update:(cv::Point3i&)point {
self.x = point.x;
self.y = point.y;
self.z = point.z;
}
- (void)set:(NSArray<NSNumber*>*)vals {
self.x = (vals != nil && vals.count > 0) ? vals[0].intValue : 0;
self.y = (vals != nil && vals.count > 1) ? vals[1].intValue : 0;
self.z = (vals != nil && vals.count > 2) ? vals[2].intValue : 0;
}
- (Point3i*) clone {
return [[Point3i alloc] initWithX:self.x y:self.y z:self.z];
}
- (double)dot:(Point3i*)point {
return self.x * point.x + self.y * point.y + self.z * point.z;
}
- (Point3i*)cross:(Point3i*)point {
return [[Point3i alloc] initWithX:(self.y * point.z - self.z * point.y) y:(self.z * point.x - self.x * point.z) z:(self.x * point.y - self.y * point.x)];
}
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
} else if (![other isKindOfClass:[Point3i class]]) {
return NO;
} else {
Point3i* point = (Point3i*)other;
return self.x == point.x && self.y == point.y && self.z == point.z;
}
}
- (NSUInteger)hash {
int prime = 31;
uint32_t result = 1;
result = prime * result + self.x;
result = prime * result + self.y;
result = prime * result + self.z;
return result;
}
- (NSString *)description {
return [NSString stringWithFormat:@"Point3i {%d,%d,%d}", self.x, self.y, self.z];
}
@end

View File

@ -0,0 +1,95 @@
//
// Range.h
//
// Created by Giles Payne on 2019/10/08.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Represents a range of dimension indices
*/
CV_EXPORTS @interface Range : NSObject
#pragma mark - Properties
@property int start;
@property int end;
#pragma mark - Constructors
- (instancetype)init;
- (instancetype)initWithStart:(int)start end:(int)end;
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#pragma mark - Methods
/**
* The size of the range
*/
- (int)size;
/**
* Determines if the range is empty
*/
- (BOOL)empty;
/**
* Creates a range representing all possible indices for a particular dimension
*/
+ (Range*)all;
/**
* Calculates the intersection of the range with another range
* @param r1 The other range
*/
- (Range*)intersection:(Range*)r1;
/**
* Adjusts each of the range limts
* @param delta The amount of the adjustment
*/
- (Range*)shift:(int)delta;
/**
* Set the range limits from the values of an array
* @param vals The array of values from which to set the range limits
*/
- (void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
# pragma mark - Common Methods
/**
* Clone object
*/
- (Range*)clone;
/**
* Compare for equality
* @param other Object to compare
*/
- (BOOL)isEqual:(nullable id)object;
/**
* Calculate hash value for this object
*/
- (NSUInteger)hash;
/**
* Returns a string that describes the contents of the object
*/
- (NSString*)description;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,86 @@
//
// Range.m
//
// Created by Giles Payne on 2019/10/08.
//
#import "Range.h"
@implementation Range
- (instancetype)init {
return [self initWithStart:0 end: 0];
}
- (instancetype)initWithStart:(int)start end:(int)end {
self = [super init];
if (self != nil) {
self.start = start;
self.end = end;
}
return self;
}
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
self = [self init];
if (self != nil) {
[self set:vals];
}
return self;
}
- (void)set:(NSArray<NSNumber*>*)vals {
self.start = (vals != nil && vals.count > 0) ? vals[0].intValue : 0;
self.end = (vals != nil && vals.count > 1 ) ? vals[1].intValue : 0;
}
- (int)size {
return [self empty] ? 0 : self.end - self.start;
}
- (BOOL)empty {
return self.end <= self.start;
}
+ (Range*)all {
return [[Range alloc] initWithStart:INT_MIN end:INT_MAX];
}
- (Range*)intersection:(Range*)r1 {
Range* out = [[Range alloc] initWithStart:MAX(r1.start, self.start) end:MIN(r1.end, self.end)];
out.end = MAX(out.end, out.start);
return out;
}
- (Range*)shift:(int)delta {
return [[Range alloc] initWithStart:self.start + delta end:self.end + delta];
}
- (Range*)clone {
return [[Range alloc] initWithStart:self.start end:self.end];
}
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
} else if (![other isKindOfClass:[Range class]]) {
return NO;
} else {
Range* it = (Range*)other;
return self.start == it.start && self.end == it.end;
}
}
- (NSUInteger)hash {
int prime = 31;
uint32_t result = 1;
result = prime * result + self.start;
result = prime * result + self.end;
return result;
}
- (NSString *)description {
return [NSString stringWithFormat:@"Range {%d, %d}", self.start, self.end];
}
@end

View File

@ -0,0 +1,113 @@
//
// Rect.h
//
// Created by Giles Payne on 2019/10/09.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
@class Point2d;
@class Size2d;
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Represents a rectange the coordinate and dimension values of which are of type `double`
*/
CV_EXPORTS @interface Rect2d : NSObject
#pragma mark - Properties
@property double x;
@property double y;
@property double width;
@property double height;
#ifdef __cplusplus
@property(readonly) cv::Rect2d& nativeRef;
#endif
#pragma mark - Constructors
- (instancetype)init;
- (instancetype)initWithX:(double)x y:(double)y width:(double)width height:(double)height;
- (instancetype)initWithPoint:(Point2d*)point1 point:(Point2d*)point2;
- (instancetype)initWithPoint:(Point2d*)point size:(Size2d*)size;
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#ifdef __cplusplus
+ (instancetype)fromNative:(cv::Rect2d&)point;
#endif
#pragma mark - Methods
/**
* Returns the top left coordinate of the rectangle
*/
- (Point2d*)tl;
/**
* Returns the bottom right coordinate of the rectangle
*/
- (Point2d*)br;
/**
* Returns the size of the rectangle
*/
- (Size2d*)size;
/**
* Returns the area of the rectangle
*/
- (double)area;
/**
* Determines if the rectangle is empty
*/
- (BOOL)empty;
/**
* Determines if the rectangle contains a given point
* @param point The point
*/
- (BOOL)contains:(Point2d*)point;
/**
* Set the rectangle coordinates and dimensions from the values of an array
* @param vals The array of values from which to set the rectangle coordinates and dimensions
*/
- (void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
#pragma mark - Common Methods
/**
* Clone object
*/
- (Rect2d*)clone;
/**
* Compare for equality
* @param other Object to compare
*/
- (BOOL)isEqual:(nullable id)object;
/**
* Calculate hash value for this object
*/
- (NSUInteger)hash;
/**
* Returns a string that describes the contents of the object
*/
- (NSString*)description;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,156 @@
//
// Rect2d.mm
//
// Created by Giles Payne on 2019/10/09.
//
#import "Rect2d.h"
#import "Point2d.h"
#import "Size2d.h"
@implementation Rect2d {
cv::Rect2d native;
}
- (double)x {
return native.x;
}
- (void)setX:(double)val {
native.x = val;
}
- (double)y {
return native.y;
}
- (void)setY:(double)val {
native.y = val;
}
- (double)width {
return native.width;
}
- (void)setWidth:(double)val {
native.width = val;
}
- (double)height {
return native.height;
}
- (void)setHeight:(double)val {
native.height = val;
}
- (cv::Rect2d&)nativeRef {
return native;
}
- (instancetype)initWithX:(double)x y:(double)y width:(double)width height:(double)height {
self = [super init];
if (self) {
self.x = x;
self.y = y;
self.width = width;
self.height = height;
}
return self;
}
- (instancetype)init {
return [self initWithX:0 y:0 width:0 height:0];
}
- (instancetype)initWithPoint:(Point2d*)point1 point:(Point2d*)point2 {
double x = (point1.x < point2.x ? point1.x : point2.x);
double y = (point1.y < point2.y ? point1.y : point2.y);
double width = (point1.x > point2.x ? point1.x : point2.x) - x;
double height = (point1.y > point2.y ? point1.y : point2.y) - y;
return [self initWithX:x y:y width:width height:height];
}
- (instancetype)initWithPoint:(Point2d*)point size:(Size2d*)size {
return [self initWithX:point.x y:point.y width:size.width height:size.height];
}
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
self = [super init];
if (self) {
[self set:vals];
}
return self;
}
+ (instancetype)fromNative:(cv::Rect2d&)rect {
return [[Rect2d alloc] initWithX:rect.x y:rect.y width:rect.width height:rect.height];
}
- (Rect2d*)clone {
return [[Rect2d alloc] initWithX:self.x y:self.y width:self.width height:self.height];
}
- (Point2d*)tl {
return [[Point2d alloc] initWithX:self.x y:self.y];
}
- (Point2d*)br {
return [[Point2d alloc] initWithX:self.x + self.width y:self.y + self.height];
}
- (Size2d*)size {
return [[Size2d alloc] initWithWidth:self.width height:self.height];
}
- (double)area {
return self.width * self.height;
}
- (BOOL)empty {
return self.width <= 0 || self.height <= 0;
}
- (BOOL)contains:(Point2d*)point {
return self.x <= point.x && point.x < self.x + self.width && self.y <= point.y && point.y < self.y + self.height;
}
- (void)set:(NSArray<NSNumber*>*)vals {
self.x = (vals != nil && vals.count > 0) ? vals[0].intValue : 0;
self.y = (vals != nil && vals.count > 1) ? vals[1].intValue : 0;
self.width = (vals != nil && vals.count > 2) ? vals[2].intValue : 0;
self.height = (vals != nil && vals.count > 3) ? vals[3].intValue : 0;
}
- (BOOL)isEqual:(id)other{
if (other == self) {
return YES;
} else if (![other isKindOfClass:[Rect2d class]]) {
return NO;
} else {
Rect2d* rect = (Rect2d*)other;
return self.x == rect.x && self.y == rect.y && self.width == rect.width && self.height == rect.height;
}
}
#define DOUBLE_TO_BITS(x) ((Cv64suf){ .f = x }).i
- (NSUInteger)hash {
int prime = 31;
uint32_t result = 1;
int64_t temp = DOUBLE_TO_BITS(self.x);
result = prime * result + (int32_t) (temp ^ (temp >> 32));
temp = DOUBLE_TO_BITS(self.y);
result = prime * result + (int32_t) (temp ^ (temp >> 32));
temp = DOUBLE_TO_BITS(self.width);
result = prime * result + (int32_t) (temp ^ (temp >> 32));
temp = DOUBLE_TO_BITS(self.height);
result = prime * result + (int32_t) (temp ^ (temp >> 32));
return result;
}
- (NSString *)description {
return [NSString stringWithFormat:@"Rect2d {%lf,%lf,%lf,%lf}", self.x, self.y, self.width, self.height];
}
@end

View File

@ -0,0 +1,113 @@
//
// Rect.h
//
// Created by Giles Payne on 2019/10/09.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
@class Point2f;
@class Size2f;
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Represents a rectange the coordinate and dimension values of which are of type `float`
*/
CV_EXPORTS @interface Rect2f : NSObject
#pragma mark - Properties
@property float x;
@property float y;
@property float width;
@property float height;
#ifdef __cplusplus
@property(readonly) cv::Rect2f& nativeRef;
#endif
#pragma mark - Constructors
- (instancetype)init;
- (instancetype)initWithX:(float)x y:(float)y width:(float)width height:(float)height;
- (instancetype)initWithPoint:(Point2f*)point1 point:(Point2f*)point2;
- (instancetype)initWithPoint:(Point2f*)point size:(Size2f*)size;
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#ifdef __cplusplus
+ (instancetype)fromNative:(cv::Rect2f&)point;
#endif
#pragma mark - Methods
/**
* Returns the top left coordinate of the rectangle
*/
- (Point2f*)tl;
/**
* Returns the bottom right coordinate of the rectangle
*/
- (Point2f*)br;
/**
* Returns the size of the rectangle
*/
- (Size2f*)size;
/**
* Returns the area of the rectangle
*/
- (double)area;
/**
* Determines if the rectangle is empty
*/
- (BOOL)empty;
/**
* Determines if the rectangle contains a given point
* @param point The point
*/
- (BOOL)contains:(Point2f*)point;
/**
* Set the rectangle coordinates and dimensions from the values of an array
* @param vals The array of values from which to set the rectangle coordinates and dimensions
*/
- (void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
#pragma mark - Common Methods
/**
* Clone object
*/
- (Rect2f*)clone;
/**
* Compare for equality
* @param other Object to compare
*/
- (BOOL)isEqual:(nullable id)object;
/**
* Calculate hash value for this object
*/
- (NSUInteger)hash;
/**
* Returns a string that describes the contents of the object
*/
- (NSString*)description;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,152 @@
//
// Rect2d.mm
//
// Created by Giles Payne on 2019/10/09.
//
#import "Rect2f.h"
#import "Point2f.h"
#import "Size2f.h"
@implementation Rect2f {
cv::Rect2f native;
}
- (float)x {
return native.x;
}
- (void)setX:(float)val {
native.x = val;
}
- (float)y {
return native.y;
}
- (void)setY:(float)val {
native.y = val;
}
- (float)width {
return native.width;
}
- (void)setWidth:(float)val {
native.width = val;
}
- (float)height {
return native.height;
}
- (void)setHeight:(float)val {
native.height = val;
}
- (cv::Rect2f&)nativeRef {
return native;
}
- (instancetype)initWithX:(float)x y:(float)y width:(float)width height:(float)height {
self = [super init];
if (self) {
self.x = x;
self.y = y;
self.width = width;
self.height = height;
}
return self;
}
- (instancetype)init {
return [self initWithX:0 y:0 width:0 height:0];
}
- (instancetype)initWithPoint:(Point2f*)point1 point:(Point2f*)point2 {
float x = (point1.x < point2.x ? point1.x : point2.x);
float y = (point1.y < point2.y ? point1.y : point2.y);
float width = (point1.x > point2.x ? point1.x : point2.x) - x;
float height = (point1.y > point2.y ? point1.y : point2.y) - y;
return [self initWithX:x y:y width:width height:height];
}
- (instancetype)initWithPoint:(Point2f*)point size:(Size2f*)size {
return [self initWithX:point.x y:point.y width:size.width height:size.height];
}
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
self = [super init];
if (self) {
[self set:vals];
}
return self;
}
+ (instancetype)fromNative:(cv::Rect2f&)rect {
return [[Rect2f alloc] initWithX:rect.x y:rect.y width:rect.width height:rect.height];
}
- (Rect2f*)clone {
return [[Rect2f alloc] initWithX:self.x y:self.y width:self.width height:self.height];
}
- (Point2f*)tl {
return [[Point2f alloc] initWithX:self.x y:self.y];
}
- (Point2f*)br {
return [[Point2f alloc] initWithX:self.x + self.width y:self.y + self.height];
}
- (Size2f*)size {
return [[Size2f alloc] initWithWidth:self.width height:self.height];
}
- (double)area {
return self.width * self.height;
}
- (BOOL)empty {
return self.width <= 0 || self.height <= 0;
}
- (BOOL)contains:(Point2f*)point {
return self.x <= point.x && point.x < self.x + self.width && self.y <= point.y && point.y < self.y + self.height;
}
- (void)set:(NSArray<NSNumber*>*)vals {
self.x = (vals != nil && vals.count > 0) ? vals[0].floatValue : 0;
self.y = (vals != nil && vals.count > 1) ? vals[1].floatValue : 0;
self.width = (vals != nil && vals.count > 2) ? vals[2].floatValue : 0;
self.height = (vals != nil && vals.count > 3) ? vals[3].floatValue : 0;
}
- (BOOL)isEqual:(id)other{
if (other == self) {
return YES;
} else if (![other isKindOfClass:[Rect2f class]]) {
return NO;
} else {
Rect2f* rect = (Rect2f*)other;
return self.x == rect.x && self.y == rect.y && self.width == rect.width && self.height == rect.height;
}
}
#define FLOAT_TO_BITS(x) ((Cv32suf){ .f = x }).i
- (NSUInteger)hash {
int prime = 31;
uint32_t result = 1;
result = prime * result + FLOAT_TO_BITS(self.x);
result = prime * result + FLOAT_TO_BITS(self.y);
result = prime * result + FLOAT_TO_BITS(self.width);
result = prime * result + FLOAT_TO_BITS(self.height);
return result;
}
- (NSString *)description {
return [NSString stringWithFormat:@"Rect2f {%lf,%lf,%lf,%lf}", self.x, self.y, self.width, self.height];
}
@end

View File

@ -0,0 +1,113 @@
//
// Rect2i.h
//
// Created by Giles Payne on 2019/10/09.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
@class Point2i;
@class Size2i;
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Represents a rectange the coordinate and dimension values of which are of type `int`
*/
CV_EXPORTS @interface Rect2i : NSObject
#pragma mark - Properties
@property int x;
@property int y;
@property int width;
@property int height;
#ifdef __cplusplus
@property(readonly) cv::Rect2i& nativeRef;
#endif
#pragma mark - Constructors
- (instancetype)init;
- (instancetype)initWithX:(int)x y:(int)y width:(int)width height:(int)height;
- (instancetype)initWithPoint:(Point2i*)point1 point:(Point2i*)point2;
- (instancetype)initWithPoint:(Point2i*)point size:(Size2i*)size;
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#ifdef __cplusplus
+ (instancetype)fromNative:(cv::Rect&)point;
#endif
#pragma mark - Methods
/**
* Returns the top left coordinate of the rectangle
*/
- (Point2i*)tl;
/**
* Returns the bottom right coordinate of the rectangle
*/
- (Point2i*)br;
/**
* Returns the size of the rectangle
*/
- (Size2i*)size;
/**
* Returns the area of the rectangle
*/
- (double)area;
/**
* Determines if the rectangle is empty
*/
- (BOOL)empty;
/**
* Determines if the rectangle contains a given point
* @param point The point
*/
- (BOOL)contains:(Point2i*)point;
/**
* Set the rectangle coordinates and dimensions from the values of an array
* @param vals The array of values from which to set the rectangle coordinates and dimensions
*/
- (void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
#pragma mark - Common Methods
/**
* Clone object
*/
- (Rect2i*)clone;
/**
* Compare for equality
* @param other Object to compare
*/
- (BOOL)isEqual:(nullable id)object;
/**
* Calculate hash value for this object
*/
- (NSUInteger)hash;
/**
* Returns a string that describes the contents of the object
*/
- (NSString*)description;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,150 @@
//
// Rect2i.m
//
// Created by Giles Payne on 2019/10/09.
//
#import "Rect2i.h"
#import "Point2i.h"
#import "Size2i.h"
@implementation Rect2i {
cv::Rect2i native;
}
- (int)x {
return native.x;
}
- (void)setX:(int)val {
native.x = val;
}
- (int)y {
return native.y;
}
- (void)setY:(int)val {
native.y = val;
}
- (int)width {
return native.width;
}
- (void)setWidth:(int)val {
native.width = val;
}
- (int)height {
return native.height;
}
- (void)setHeight:(int)val {
native.height = val;
}
- (cv::Rect&)nativeRef {
return native;
}
- (instancetype)initWithX:(int)x y:(int)y width:(int)width height:(int)height {
self = [super init];
if (self) {
self.x = x;
self.y = y;
self.width = width;
self.height = height;
}
return self;
}
- (instancetype)init {
return [self initWithX:0 y:0 width:0 height:0];
}
- (instancetype)initWithPoint:(Point2i*)point1 point:(Point2i*)point2 {
int x = (point1.x < point2.x ? point1.x : point2.x);
int y = (point1.y < point2.y ? point1.y : point2.y);
int width = (point1.x > point2.x ? point1.x : point2.x) - x;
int height = (point1.y > point2.y ? point1.y : point2.y) - y;
return [self initWithX:x y:y width:width height:height];
}
- (instancetype)initWithPoint:(Point2i*)point size:(Size2i*)size {
return [self initWithX:point.x y:point.y width:size.width height:size.height];
}
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
self = [super init];
if (self) {
[self set:vals];
}
return self;
}
+ (instancetype)fromNative:(cv::Rect&)rect {
return [[Rect2i alloc] initWithX:rect.x y:rect.y width:rect.width height:rect.height];
}
- (Rect2i*)clone {
return [[Rect2i alloc] initWithX:self.x y:self.y width:self.width height:self.height];
}
- (Point2i*)tl {
return [[Point2i alloc] initWithX:self.x y:self.y];
}
- (Point2i*)br {
return [[Point2i alloc] initWithX:self.x + self.width y:self.y + self.height];
}
- (Size2i*)size {
return [[Size2i alloc] initWithWidth:self.width height:self.height];
}
- (double)area {
return self.width * self.height;
}
- (BOOL)empty {
return self.width <= 0 || self.height <= 0;
}
- (BOOL)contains:(Point2i*)point {
return self.x <= point.x && point.x < self.x + self.width && self.y <= point.y && point.y < self.y + self.height;
}
- (void)set:(NSArray<NSNumber*>*)vals {
self.x = (vals != nil && vals.count > 0) ? vals[0].intValue : 0;
self.y = (vals != nil && vals.count > 1) ? vals[1].intValue : 0;
self.width = (vals != nil && vals.count > 2) ? vals[2].intValue : 0;
self.height = (vals != nil && vals.count > 3) ? vals[3].intValue : 0;
}
- (BOOL)isEqual:(id)other{
if (other == self) {
return YES;
} else if (![other isKindOfClass:[Rect2i class]]) {
return NO;
} else {
Rect2i* rect = (Rect2i*)other;
return self.x == rect.x && self.y == rect.y && self.width == rect.width && self.height == rect.height;
}
}
- (NSUInteger)hash {
int prime = 31;
uint32_t result = 1;
result = prime * result + self.x;
result = prime * result + self.y;
result = prime * result + self.width;
result = prime * result + self.height;
return result;
}
- (NSString *)description {
return [NSString stringWithFormat:@"Rect2i {%d,%d,%d,%d}", self.x, self.y, self.width, self.height];
}
@end

View File

@ -0,0 +1,88 @@
//
// RotatedRect.h
//
// Created by Giles Payne on 2019/12/26.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
@class Point2f;
@class Size2f;
@class Rect2f;
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Represents a rotated rectangle on a plane
*/
CV_EXPORTS @interface RotatedRect : NSObject
#pragma mark - Properties
@property Point2f* center;
@property Size2f* size;
@property double angle;
#ifdef __cplusplus
@property(readonly) cv::RotatedRect& nativeRef;
#endif
#pragma mark - Constructors
- (instancetype)init;
- (instancetype)initWithCenter:(Point2f*)center size:(Size2f*)size angle:(double)angle;
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#ifdef __cplusplus
+ (instancetype)fromNative:(cv::RotatedRect&)rotatedRect;
#endif
#pragma mark - Methods
/**
* Returns the corner points of the rotated rectangle as an array
*/
- (NSArray<Point2f*>*)points;
/**
* Returns the bounding (non-rotated) rectangle of the rotated rectangle
*/
- (Rect2f*)boundingRect;
/**
* Set the rotated rectangle coordinates, dimensions and angle of rotation from the values of an array
* @param vals The array of values from which to set the rotated rectangle coordinates, dimensions and angle of rotation
*/
- (void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
#pragma mark - Common Methods
/**
* Clone object
*/
- (RotatedRect*)clone;
/**
* Compare for equality
* @param other Object to compare
*/
- (BOOL)isEqual:(nullable id)object;
/**
* Calculate hash value for this object
*/
- (NSUInteger)hash;
/**
* Returns a string that describes the contents of the object
*/
- (NSString*)description;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,115 @@
//
// RotatedRect.m
//
// Created by Giles Payne on 2019/12/26.
//
#import "RotatedRect.h"
#import "Point2f.h"
#import "Size2f.h"
#import "Rect2f.h"
#include <math.h>
@implementation RotatedRect {
cv::RotatedRect native;
}
- (cv::RotatedRect&)nativeRef {
native.center.x = self.center.x;
native.center.y = self.center.y;
native.size.width = self.size.width;
native.size.height = self.size.height;
native.angle = self.angle;
return native;
}
- (instancetype)init {
return [self initWithCenter:[Point2f new] size:[Size2f new] angle:0.0];
}
- (instancetype)initWithCenter:(Point2f*)center size:(Size2f*)size angle:(double)angle {
self = [super init];
if (self) {
self.center = center;
self.size = size;
self.angle = angle;
}
return self;
}
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
self = [self init];
if (self) {
[self set:vals];
}
return self;
}
+ (instancetype)fromNative:(cv::RotatedRect&)rotatedRect {
return [[RotatedRect alloc] initWithCenter:[Point2f fromNative:rotatedRect.center] size:[Size2f fromNative:rotatedRect.size] angle:rotatedRect.angle];
}
- (void)set:(NSArray<NSNumber*>*)vals {
self.center.x = (vals != nil && vals.count > 0) ? vals[0].floatValue : 0.0;
self.center.y = (vals != nil && vals.count > 1) ? vals[1].floatValue : 0.0;
self.size.width = (vals != nil && vals.count > 2) ? vals[2].floatValue : 0.0;
self.size.height = (vals != nil && vals.count > 3) ? vals[3].floatValue : 0.0;
self.angle = (vals != nil && vals.count > 4) ? vals[4].doubleValue : 0.0;
}
- (NSArray<Point2f*>*)points {
double angleRadians = self.angle * M_PI / 180.0;
double b = cos(angleRadians) * 0.5;
double a = sin(angleRadians) * 0.5f;
Point2f* p0 = [[Point2f alloc] initWithX:self.center.x - a * self.size.height - b * self.size.width y:self.center.y + b * self.size.height - a * self.size.width];
Point2f* p1 = [[Point2f alloc] initWithX:self.center.x + a * self.size.height - b * self.size.width y:self.center.y - b * self.size.height - a * self.size.width];
Point2f* p2 = [[Point2f alloc] initWithX:2 * self.center.x - p0.x y:2 * self.center.y - p0.y];
Point2f* p3 = [[Point2f alloc] initWithX:2 * self.center.x - p1.x y:2 * self.center.y - p1.y];
return [NSArray arrayWithObjects:p0, p1, p2, p3, nil];
}
- (Rect2f*)boundingRect {
NSArray<Point2f*>* pts = [self points];
Rect2f* rect = [[Rect2f alloc] initWithX:(int)floor(MIN(MIN(MIN(pts[0].x, pts[1].x), pts[2].x), pts[3].x)) y:(int)floor(MIN(MIN(MIN(pts[0].y, pts[1].y), pts[2].y), pts[3].y)) width:(int)ceil(MAX(MAX(MAX(pts[0].x, pts[1].x), pts[2].x), pts[3].x)) height:(int)ceil(MAX(MAX(MAX(pts[0].y, pts[1].y), pts[2].y), pts[3].y))];
rect.width -= rect.x - 1;
rect.height -= rect.y - 1;
return rect;
}
- (RotatedRect*)clone {
return [[RotatedRect alloc] initWithCenter:[self.center clone] size:[self.size clone] angle:self.angle];
}
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
} else if (![other isKindOfClass:[RotatedRect class]]) {
return NO;
} else {
RotatedRect* rect = (RotatedRect*)other;
return [self.center isEqual:rect.center] && [self.size isEqual:rect.size] && self.angle == rect.angle;
}
}
#define FLOAT_TO_BITS(x) ((Cv32suf){ .f = x }).i
#define DOUBLE_TO_BITS(x) ((Cv64suf){ .f = x }).i
- (NSUInteger)hash {
int prime = 31;
uint32_t result = 1;
result = prime * result + FLOAT_TO_BITS(self.center.x);
result = prime * result + FLOAT_TO_BITS(self.center.y);
result = prime * result + FLOAT_TO_BITS(self.size.width);
result = prime * result + FLOAT_TO_BITS(self.size.height);
int64_t temp = DOUBLE_TO_BITS(self.angle);
result = prime * result + (int32_t) (temp ^ (temp >> 32));
return result;
}
- (NSString*)description {
return [NSString stringWithFormat:@"RotatedRect {%@,%@,%lf}", self.center.description, self.size.description, self.angle];
}
@end

View File

@ -0,0 +1,98 @@
//
// Scalar.h
//
// Created by Giles Payne on 2019/10/06.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Represents a four element vector
*/
CV_EXPORTS @interface Scalar : NSObject
#pragma mark - Properties
@property(readonly) NSArray<NSNumber*>* val;
#ifdef __cplusplus
@property(readonly) cv::Scalar& nativeRef;
#endif
#pragma mark - Constructors
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
- (instancetype)initWithV0:(double)v0 v1:(double)v1 v2:(double)v2 v3:(double)v3 NS_SWIFT_NAME(init(_:_:_:_:));
- (instancetype)initWithV0:(double)v0 v1:(double)v1 v2:(double)v2 NS_SWIFT_NAME(init(_:_:_:));
- (instancetype)initWithV0:(double)v0 v1:(double)v1 NS_SWIFT_NAME(init(_:_:));
- (instancetype)initWithV0:(double)v0 NS_SWIFT_NAME(init(_:));
#ifdef __cplusplus
+ (instancetype)fromNative:(cv::Scalar&)nativeScalar;
#endif
#pragma mark - Methods
/**
* Creates a scalar with all elements of the same value
* @param v The value to set each element to
*/
+ (Scalar*)all:(double)v;
/**
* Calculates per-element product with another Scalar and a scale factor
* @param it The other Scalar
* @param scale The scale factor
*/
- (Scalar*)mul:(Scalar*)it scale:(double)scale;
/**
* Calculates per-element product with another Scalar
* @param it The other Scalar
*/
- (Scalar*)mul:(Scalar*)it;
/**
* Returns (v0, -v1, -v2, -v3)
*/
- (Scalar*)conj;
/**
* Returns true iff v1 == v2 == v3 == 0
*/
- (BOOL)isReal;
#pragma mark - Common Methods
/**
* Clone object
*/
- (Scalar*)clone;
/**
* Compare for equality
* @param other Object to compare
*/
- (BOOL)isEqual:(nullable id)object;
/**
* Calculate hash value for this object
*/
- (NSUInteger)hash;
/**
* Returns a string that describes the contents of the object
*/
- (NSString*)description;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,118 @@
//
// Scalar.mm
//
// Created by Giles Payne on 2019/10/06.
//
#import "Scalar.h"
double getVal(NSArray<NSNumber*>* vals, int index) {
return [vals count] > index ? vals[index].doubleValue : 0;
}
@implementation Scalar {
cv::Scalar native;
}
- (NSArray<NSNumber*>*)val {
return @[[NSNumber numberWithDouble:native.val[0]], [NSNumber numberWithDouble:native.val[1]], [NSNumber numberWithDouble:native.val[2]], [NSNumber numberWithDouble:native.val[3]]];
}
#ifdef __cplusplus
- (cv::Scalar&)nativeRef {
return native;
}
#endif
- (instancetype)initWithVals:(NSArray<NSNumber*> *)vals {
return [self initWithV0:getVal(vals, 0) v1:getVal(vals, 1) v2:getVal(vals, 2) v3:getVal(vals, 3)];
}
- (instancetype)initWithV0:(double)v0 v1:(double)v1 v2:(double)v2 v3:(double)v3 {
self = [super init];
if (self != nil) {
native.val[0] = v0;
native.val[1] = v1;
native.val[2] = v2;
native.val[3] = v3;
}
return self;
}
- (instancetype)initWithV0:(double)v0 v1:(double)v1 v2:(double)v2 {
return [self initWithV0:v0 v1:v1 v2:v2 v3:0];
}
- (instancetype)initWithV0:(double)v0 v1:(double)v1 {
return [self initWithV0:v0 v1:v1 v2:0 v3:0];
}
- (instancetype)initWithV0:(double)v0 {
return [self initWithV0:v0 v1:0 v2:0 v3:0];
}
#ifdef __cplusplus
+ (instancetype)fromNative:(cv::Scalar&)nativeScalar {
return [[Scalar alloc] initWithV0:nativeScalar.val[0] v1:nativeScalar.val[1] v2:nativeScalar.val[2] v3:nativeScalar.val[3]];
}
#endif
+ (Scalar*)all:(double)v {
return [[Scalar alloc] initWithV0:v v1:v v2:v v3:v];
}
- (Scalar*)clone {
return [Scalar fromNative:self.nativeRef];
}
- (Scalar*)mul:(Scalar*)it scale:(double)scale {
return [[Scalar alloc] initWithV0:self.nativeRef.val[0]*it.nativeRef.val[0]*scale v1:self.nativeRef.val[1]*it.nativeRef.val[1]*scale v2:self.nativeRef.val[2]*it.nativeRef.val[2]*scale v3:self.nativeRef.val[3]*it.nativeRef.val[3]*scale];
}
- (Scalar*)mul:(Scalar*)it {
return [self mul:it scale:1];
}
- (Scalar*)conj {
return [[Scalar alloc] initWithV0:self.nativeRef.val[0] v1:-self.nativeRef.val[1] v2:-self.nativeRef.val[2] v3:-self.nativeRef.val[3]];
}
- (BOOL)isReal {
return self.nativeRef.val[1] == self.nativeRef.val[2] == self.nativeRef.val[3] == 0;
}
- (BOOL)isEqual:(id)other
{
if (other == self) {
return YES;
} else if (![other isKindOfClass:[Scalar class]]) {
return NO;
} else {
Scalar* it = (Scalar*) other;
return it.nativeRef.val[0] == self.nativeRef.val[0] && it.nativeRef.val[1] == self.nativeRef.val[1] && it.nativeRef.val[2] == self.nativeRef.val[2] && it.nativeRef.val[3] == self.nativeRef.val[3];
}
}
#define DOUBLE_TO_BITS(x) ((Cv64suf){ .f = x }).i
- (NSUInteger)hash
{
int prime = 31;
uint32_t result = 1;
int64_t temp = DOUBLE_TO_BITS(self.nativeRef.val[0]);
result = prime * result + (int32_t) (temp ^ (temp >> 32));
temp = DOUBLE_TO_BITS(self.nativeRef.val[1]);
result = prime * result + (int32_t) (temp ^ (temp >> 32));
temp = DOUBLE_TO_BITS(self.nativeRef.val[2]);
result = prime * result + (int32_t) (temp ^ (temp >> 32));
temp = DOUBLE_TO_BITS(self.nativeRef.val[3]);
result = prime * result + (int32_t) (temp ^ (temp >> 32));
return result;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"Scalar [%lf, %lf, %lf, %lf]", self.nativeRef.val[0], self.nativeRef.val[1], self.nativeRef.val[2], self.nativeRef.val[3]];
}
@end

View File

@ -0,0 +1,89 @@
//
// Size2d.h
//
// Created by Giles Payne on 2019/10/06.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
@class Point2d;
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Represents the dimensions of a rectangle the values of which are of type `double`
*/
CV_EXPORTS @interface Size2d : NSObject
#pragma mark - Properties
@property double width;
@property double height;
#ifdef __cplusplus
@property(readonly) cv::Size2d& nativeRef;
#endif
#pragma mark - Constructors
- (instancetype)init;
- (instancetype)initWithWidth:(double)width height:(double)height;
- (instancetype)initWithPoint:(Point2d*)point;
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#ifdef __cplusplus
+ (instancetype)fromNative:(cv::Size2d&)size;
#endif
+ (instancetype)width:(double)width height:(double)height;
#pragma mark - Methods
/**
* Returns the area of a rectangle with corresponding dimensions
*/
- (double)area;
/**
* Determines if a rectangle with corresponding dimensions has area of zero
*/
- (BOOL)empty;
/**
* Set the dimensions from the values of an array
* @param vals The array of values from which to set the dimensions
*/
- (void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
#pragma mark - Common Methods
/**
* Clone object
*/
- (Size2d*)clone;
/**
* Compare for equality
* @param other Object to compare
*/
- (BOOL)isEqual:(nullable id)object;
/**
* Calculate hash value for this object
*/
- (NSUInteger)hash;
/**
* Returns a string that describes the contents of the object
*/
- (NSString*)description;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,111 @@
//
// Size2d.mm
//
// Created by Giles Payne on 2019/10/06.
//
#import "Size2d.h"
#import "Point2d.h"
@implementation Size2d {
cv::Size2d native;
}
- (double)width {
return native.width;
}
- (void)setWidth:(double)val {
native.width = val;
}
- (double)height {
return native.height;
}
- (void)setHeight:(double)val {
native.height = val;
}
- (cv::Size2d&)nativeRef {
return native;
}
- (instancetype)init {
return [self initWithWidth:0 height:0];
}
- (instancetype)initWithWidth:(double)width height:(double)height {
self = [super init];
if (self) {
self.width = width;
self.height = height;
}
return self;
}
- (instancetype)initWithPoint:(Point2d*)point {
return [self initWithWidth:point.x height:point.y];
}
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
self = [super init];
if (self) {
[self set:vals];
}
return self;
}
+ (instancetype)fromNative:(cv::Size2d&)size {
return [[Size2d alloc] initWithWidth:size.width height:size.height];
}
+ (instancetype)width:(double)width height:(double)height {
return [[Size2d alloc] initWithWidth:width height:height];
}
- (double)area {
return self.width * self.height;
}
- (BOOL)empty {
return self.width <= 0 || self.height <= 0;
}
- (void)set:(NSArray<NSNumber*>*)vals {
self.width = (vals != nil && vals.count > 0) ? vals[0].doubleValue : 0;
self.height = (vals != nil && vals.count > 1) ? vals[1].doubleValue : 0;
}
- (Size2d*)clone {
return [[Size2d alloc] initWithWidth:self.width height:self.height];
}
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
} else if (![other isKindOfClass:[Size2d class]]) {
return NO;
} else {
Size2d* it = (Size2d*)other;
return self.width == it.width && self.height == it.height;
}
}
#define DOUBLE_TO_BITS(x) ((Cv64suf){ .f = x }).i
- (NSUInteger)hash {
int prime = 31;
uint32_t result = 1;
int64_t temp = DOUBLE_TO_BITS(self.height);
result = prime * result + (int32_t) (temp ^ (temp >> 32));
temp = DOUBLE_TO_BITS(self.width);
result = prime * result + (int32_t) (temp ^ (temp >> 32));
return result;
}
- (NSString *)description {
return [NSString stringWithFormat:@"Size2d {%lf,%lf}", self.width, self.height];
}
@end

View File

@ -0,0 +1,89 @@
//
// Size2f.h
//
// Created by Giles Payne on 2019/10/06.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
@class Point2f;
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Represents the dimensions of a rectangle the values of which are of type `float`
*/
CV_EXPORTS @interface Size2f : NSObject
#pragma mark - Properties
@property float width;
@property float height;
#ifdef __cplusplus
@property(readonly) cv::Size2f& nativeRef;
#endif
#pragma mark - Constructors
- (instancetype)init;
- (instancetype)initWithWidth:(float)width height:(float)height;
- (instancetype)initWithPoint:(Point2f*)point;
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#ifdef __cplusplus
+ (instancetype)fromNative:(cv::Size2f&)size;
#endif
+ (instancetype)width:(float)width height:(float)height;
#pragma mark - Methods
/**
* Returns the area of a rectangle with corresponding dimensions
*/
- (double)area;
/**
* Determines if a rectangle with corresponding dimensions has area of zero
*/
- (BOOL)empty;
/**
* Set the dimensions from the values of an array
* @param vals The array of values from which to set the dimensions
*/
- (void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
#pragma mark - Common Methods
/**
* Clone object
*/
- (Size2f*)clone;
/**
* Compare for equality
* @param other Object to compare
*/
- (BOOL)isEqual:(nullable id)object;
/**
* Calculate hash value for this object
*/
- (NSUInteger)hash;
/**
* Returns a string that describes the contents of the object
*/
- (NSString*)description;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,109 @@
//
// Size2f.mm
//
// Created by Giles Payne on 2019/10/06.
//
#import "Size2f.h"
#import "Point2f.h"
@implementation Size2f {
cv::Size2f native;
}
- (float)width {
return native.width;
}
- (void)setWidth:(float)val {
native.width = val;
}
- (float)height {
return native.height;
}
- (void)setHeight:(float)val {
native.height = val;
}
- (cv::Size2f&)nativeRef {
return native;
}
- (instancetype)init {
return [self initWithWidth:0 height:0];
}
- (instancetype)initWithWidth:(float)width height:(float)height {
self = [super init];
if (self) {
self.width = width;
self.height = height;
}
return self;
}
- (instancetype)initWithPoint:(Point2f*)point {
return [self initWithWidth:point.x height:point.y];
}
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
self = [super init];
if (self) {
[self set:vals];
}
return self;
}
+ (instancetype)fromNative:(cv::Size2f&)size {
return [[Size2f alloc] initWithWidth:size.width height:size.height];
}
+ (instancetype)width:(float)width height:(float)height {
return [[Size2f alloc] initWithWidth:width height:height];
}
- (double)area {
return self.width * self.height;
}
- (BOOL)empty {
return self.width <= 0 || self.height <= 0;
}
- (void)set:(NSArray<NSNumber*>*)vals {
self.width = (vals != nil && vals.count > 0) ? vals[0].floatValue : 0;
self.height = (vals != nil && vals.count > 1) ? vals[1].floatValue : 0;
}
- (Size2f*)clone {
return [[Size2f alloc] initWithWidth:self.width height:self.height];
}
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
} else if (![other isKindOfClass:[Size2f class]]) {
return NO;
} else {
Size2f* it = (Size2f*)other;
return self.width == it.width && self.height == it.height;
}
}
#define FLOAT_TO_BITS(x) ((Cv32suf){ .f = x }).i
- (NSUInteger)hash {
int prime = 31;
uint32_t result = 1;
result = prime * result + FLOAT_TO_BITS(self.height);
result = prime * result + FLOAT_TO_BITS(self.width);
return result;
}
- (NSString *)description {
return [NSString stringWithFormat:@"Size2f {%f,%f}", self.width, self.height];
}
@end

View File

@ -0,0 +1,89 @@
//
// Size2i.h
//
// Created by Giles Payne on 2019/10/06.
//
#pragma once
#ifdef __cplusplus
#import "opencv2/core.hpp"
#else
#define CV_EXPORTS
#endif
@class Point2i;
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Represents the dimensions of a rectangle the values of which are of type `int`
*/
CV_EXPORTS @interface Size2i : NSObject
#pragma mark - Properties
@property int width;
@property int height;
#ifdef __cplusplus
@property(readonly) cv::Size2i& nativeRef;
#endif
#pragma mark - Constructors
- (instancetype)init;
- (instancetype)initWithWidth:(int)width height:(int)height;
- (instancetype)initWithPoint:(Point2i*)point;
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals;
#ifdef __cplusplus
+ (instancetype)fromNative:(cv::Size2i&)size;
#endif
+ (instancetype)width:(int)width height:(int)height;
#pragma mark - Methods
/**
* Returns the area of a rectangle with corresponding dimensions
*/
- (double)area;
/**
* Determines if a rectangle with corresponding dimensions has area of zero
*/
- (BOOL)empty;
/**
* Set the dimensions from the values of an array
* @param vals The array of values from which to set the dimensions
*/
- (void)set:(NSArray<NSNumber*>*)vals NS_SWIFT_NAME(set(vals:));
#pragma mark - Common Methods
/**
* Clone object
*/
- (Size2i*)clone;
/**
* Compare for equality
* @param other Object to compare
*/
- (BOOL)isEqual:(nullable id)object;
/**
* Calculate hash value for this object
*/
- (NSUInteger)hash;
/**
* Returns a string that describes the contents of the object
*/
- (NSString*)description;
@end
NS_ASSUME_NONNULL_END

Some files were not shown because too many files have changed in this diff Show More