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

Merge pull request #17165 from komakai:objc-binding

Objc binding

* Initial work on Objective-C wrapper

* Objective-C generator script; update manually generated wrappers

* Add Mat tests

* Core Tests

* Imgproc wrapper generation and tests

* Fixes for Imgcodecs wrapper

* Miscellaneous fixes. Swift build support

* Objective-C wrapper build/install

* Add Swift wrappers for videoio/objdetect/feature2d

* Framework build;iOS support

* Fix toArray functions;Use enum types whenever possible

* Use enum types where possible;prepare test build

* Update test

* Add test runner scripts for iOS and macOS

* Add test scripts and samples

* Build fixes

* Fix build (cmake 3.17.x compatibility)

* Fix warnings

* Fix enum name conflicting handling

* Add support for document generation with Jazzy

* Swift/Native fast accessor functions

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

* Remove IntOut/FloatOut/DoubleOut classes

* Fix iOS default test platform value

* Fix samples

* Revert default framework name to opencv2

* Add converter util functions

* Fix failing test

* Fix whitespace

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

* Suppress cmake warnings

* Reduce severity of "jazzy not found" log message

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

* Use explicit returns in subscript/get implementation

* Reduce minimum required cmake version to 3.15 for Objective-C/Swift binding
Showing with 2501 additions and 0 deletions
+2501 -0
//
// KeyPoint.h
//
// Created by Giles Payne on 2019/10/08.
//
#pragma once
#ifdef __cplusplus
#import "opencv.hpp"
#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.
*/
@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
//
// KeyPoint.m
//
// Created by Giles Payne on 2019/12/25.
//
#import "KeyPoint.h"
#import "Point2f.h"
#import "CVObjcUtil.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;
}
}
- (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
//
// Mat.h
//
// Created by Giles Payne on 2019/10/06.
//
#pragma once
#ifdef __cplusplus
#import "opencv.hpp"
#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.
*/
@interface Mat : NSObject
#ifdef __cplusplus
@property(readonly) cv::Mat* nativePtr;
@property(readonly) cv::Mat& nativeRef;
#endif
#pragma mark - Constructors
- (instancetype)init;
- (void)dealloc;
#ifdef __cplusplus
- (instancetype)initWithNativeMat:(cv::Mat*)nativeMat;
+ (instancetype)fromNativePtr:(cv::Mat*)nativePtr;
+ (instancetype)fromNative:(cv::Mat&)nativeRef;
#endif
- (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;
- (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;
- (Mat*)mul:(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
This diff is collapsed.
//
// 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 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 [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(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 [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 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:[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(row: Int32, col: Int32, data:[Int8]) 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 get(row: Int32, col: Int32) -> [Double] {
return get(indices: [row, col])
}
@discardableResult func get(indices: [Int32]) -> [Double] {
return __get(indices as [NSNumber]) as! [Double]
}
}
//
// 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
*/
@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
//
// 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
//
// 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
*/
@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
This diff is collapsed.
//
// 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
*/
@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
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment