mirror of https://github.com/opencv/opencv.git
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 bindingpull/17503/head
parent
f30b5995b6
commit
02385472b6
237 changed files with 24107 additions and 28 deletions
@ -0,0 +1,5 @@ |
||||
{ |
||||
"func_arg_fix" : { |
||||
"findCirclesGrid" : { "blobDetector" : {"defval" : "cv::SimpleBlobDetector::create()"} } |
||||
} |
||||
} |
@ -0,0 +1,465 @@ |
||||
// |
||||
// Calib3dTest.swift |
||||
// |
||||
// Created by Giles Payne on 2020/05/26. |
||||
// |
||||
|
||||
import XCTest |
||||
import OpenCV |
||||
|
||||
class Calib3dTest: OpenCVTestCase { |
||||
|
||||
var size = Size() |
||||
|
||||
override func setUp() { |
||||
super.setUp() |
||||
size = Size(width: 3, height: 3) |
||||
} |
||||
|
||||
override func tearDown() { |
||||
super.tearDown() |
||||
} |
||||
|
||||
func testComposeRTMatMatMatMatMatMat() throws { |
||||
let rvec1 = Mat(rows: 3, cols: 1, type: CvType.CV_32F) |
||||
try rvec1.put(row: 0, col: 0, data: [0.5302828, 0.19925919, 0.40105945] as [Float]) |
||||
let tvec1 = Mat(rows: 3, cols: 1, type: CvType.CV_32F) |
||||
try tvec1.put(row: 0, col: 0, data: [0.81438506, 0.43713298, 0.2487897] as [Float]) |
||||
let rvec2 = Mat(rows: 3, cols: 1, type: CvType.CV_32F) |
||||
try rvec2.put(row: 0, col: 0, data: [0.77310503, 0.76209372, 0.30779448] as [Float]) |
||||
let tvec2 = Mat(rows: 3, cols: 1, type: CvType.CV_32F) |
||||
try tvec2.put(row: 0, col: 0, data: [0.70243168, 0.4784472, 0.79219002] as [Float]) |
||||
|
||||
let rvec3 = Mat() |
||||
let tvec3 = Mat() |
||||
|
||||
let outRvec = Mat(rows: 3, cols: 1, type: CvType.CV_32F) |
||||
try outRvec.put(row: 0, col: 0, data: [1.418641, 0.88665926, 0.56020796]) |
||||
let outTvec = Mat(rows: 3, cols: 1, type: CvType.CV_32F) |
||||
try outTvec.put(row: 0, col: 0, data: [1.4560841, 1.0680628, 0.81598103]) |
||||
|
||||
Calib3d.composeRT(rvec1: rvec1, tvec1: tvec1, rvec2: rvec2, tvec2: tvec2, rvec3: rvec3, tvec3: tvec3) |
||||
|
||||
try assertMatEqual(outRvec, rvec3, OpenCVTestCase.EPS) |
||||
try assertMatEqual(outTvec, tvec3, OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
func testFilterSpecklesMatDoubleIntDouble() throws { |
||||
gray_16s_1024.copy(to: dst) |
||||
let center = Point(x: gray_16s_1024.rows() / 2, y: gray_16s_1024.cols() / 2) |
||||
Imgproc.circle(img: dst, center: center, radius: 1, color: Scalar.all(4096)) |
||||
|
||||
try assertMatNotEqual(gray_16s_1024, dst) |
||||
Calib3d.filterSpeckles(img: dst, newVal: 1024.0, maxSpeckleSize: 100, maxDiff: 0.0) |
||||
try assertMatEqual(gray_16s_1024, dst) |
||||
} |
||||
|
||||
func testFindChessboardCornersMatSizeMat() { |
||||
let patternSize = Size(width: 9, height: 6) |
||||
let corners = MatOfPoint2f() |
||||
Calib3d.findChessboardCorners(image: grayChess, patternSize: patternSize, corners: corners) |
||||
XCTAssertFalse(corners.empty()) |
||||
} |
||||
|
||||
func testFindChessboardCornersMatSizeMatInt() { |
||||
let patternSize = Size(width: 9, height: 6) |
||||
let corners = MatOfPoint2f() |
||||
Calib3d.findChessboardCorners(image: grayChess, patternSize: patternSize, corners: corners, flags: Calib3d.CALIB_CB_ADAPTIVE_THRESH + Calib3d.CALIB_CB_NORMALIZE_IMAGE + Calib3d.CALIB_CB_FAST_CHECK) |
||||
XCTAssertFalse(corners.empty()) |
||||
} |
||||
|
||||
func testFind4QuadCornerSubpix() { |
||||
let patternSize = Size(width: 9, height: 6) |
||||
let corners = MatOfPoint2f() |
||||
let region_size = Size(width: 5, height: 5) |
||||
Calib3d.findChessboardCorners(image: grayChess, patternSize: patternSize, corners: corners) |
||||
Calib3d.find4QuadCornerSubpix(img: grayChess, corners: corners, region_size: region_size) |
||||
XCTAssertFalse(corners.empty()) |
||||
} |
||||
|
||||
func testFindCirclesGridMatSizeMat() { |
||||
let size = 300 |
||||
let img = Mat(rows:Int32(size), cols:Int32(size), type:CvType.CV_8U) |
||||
img.setTo(scalar: Scalar(255)) |
||||
let centers = Mat() |
||||
|
||||
XCTAssertFalse(Calib3d.findCirclesGrid(image: img, patternSize: Size(width: 5, height: 5), centers: centers)) |
||||
|
||||
for i in 0..<5 { |
||||
for j in 0..<5 { |
||||
let x = Int32(size * (2 * i + 1) / 10) |
||||
let y = Int32(size * (2 * j + 1) / 10) |
||||
let pt = Point(x: x, y: y) |
||||
Imgproc.circle(img: img, center: pt, radius: 10, color: Scalar(0), thickness: -1) |
||||
} |
||||
} |
||||
|
||||
XCTAssert(Calib3d.findCirclesGrid(image: img, patternSize:Size(width:5, height:5), centers:centers)) |
||||
|
||||
XCTAssertEqual(25, centers.rows()) |
||||
XCTAssertEqual(1, centers.cols()) |
||||
XCTAssertEqual(CvType.CV_32FC2, centers.type()) |
||||
} |
||||
|
||||
func testFindCirclesGridMatSizeMatInt() { |
||||
let size:Int32 = 300 |
||||
let img = Mat(rows:size, cols: size, type: CvType.CV_8U) |
||||
img.setTo(scalar: Scalar(255)) |
||||
let centers = Mat() |
||||
|
||||
XCTAssertFalse(Calib3d.findCirclesGrid(image: img, patternSize: Size(width: 3, height: 5), centers: centers, flags: Calib3d.CALIB_CB_CLUSTERING | Calib3d.CALIB_CB_ASYMMETRIC_GRID)) |
||||
|
||||
let step = size * 2 / 15 |
||||
let offsetx = size / 6 |
||||
let offsety = (size - 4 * step) / 2 |
||||
for i:Int32 in 0...2 { |
||||
for j:Int32 in 0...4 { |
||||
let pt = Point(x: offsetx + (2 * i + j % 2) * step, y: offsety + step * j) |
||||
Imgproc.circle(img: img, center: pt, radius: 10, color: Scalar(0), thickness: -1) |
||||
} |
||||
} |
||||
|
||||
XCTAssert(Calib3d.findCirclesGrid(image: img, patternSize: Size(width: 3, height: 5), centers: centers, flags: Calib3d.CALIB_CB_CLUSTERING | Calib3d.CALIB_CB_ASYMMETRIC_GRID)) |
||||
|
||||
XCTAssertEqual(15, centers.rows()) |
||||
XCTAssertEqual(1, centers.cols()) |
||||
XCTAssertEqual(CvType.CV_32FC2, centers.type()) |
||||
} |
||||
|
||||
func testFindHomographyListOfPointListOfPoint() throws { |
||||
let NUM:Int32 = 20 |
||||
|
||||
let originalPoints = MatOfPoint2f() |
||||
originalPoints.alloc(NUM) |
||||
let transformedPoints = MatOfPoint2f() |
||||
transformedPoints.alloc(NUM) |
||||
|
||||
for i:Int32 in 0..<NUM { |
||||
let x:Float = Float.random(in: -50...50) |
||||
let y:Float = Float.random(in: -50...50) |
||||
try originalPoints.put(row:i, col:0, data:[x, y]) |
||||
try transformedPoints.put(row:i, col:0, data:[y, x]) |
||||
} |
||||
|
||||
let hmg = Calib3d.findHomography(srcPoints: originalPoints, dstPoints: transformedPoints) |
||||
|
||||
truth = Mat(rows: 3, cols: 3, type: CvType.CV_64F) |
||||
try truth!.put(row:0, col:0, data:[0, 1, 0, 1, 0, 0, 0, 0, 1] as [Double]) |
||||
try assertMatEqual(truth!, hmg, OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
func testReprojectImageTo3DMatMatMat() throws { |
||||
let transformMatrix = Mat(rows: 4, cols: 4, type: CvType.CV_64F) |
||||
try transformMatrix.put(row:0, col:0, data:[0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] as [Double]) |
||||
|
||||
let disparity = Mat(rows: OpenCVTestCase.matSize, cols: OpenCVTestCase.matSize, type: CvType.CV_32F) |
||||
|
||||
var disp = [Float].init(repeating: 0.0, count: Int(OpenCVTestCase.matSize * OpenCVTestCase.matSize)) |
||||
for i in 0..<Int(OpenCVTestCase.matSize) { |
||||
for j in 0..<Int(OpenCVTestCase.matSize) { |
||||
disp[i * Int(OpenCVTestCase.matSize) + j] = Float(i - j) |
||||
} |
||||
} |
||||
try disparity.put(row:0, col:0, data:disp) |
||||
|
||||
let _3dPoints = Mat() |
||||
|
||||
Calib3d.reprojectImageTo3D(disparity: disparity, _3dImage: _3dPoints, Q: transformMatrix) |
||||
|
||||
XCTAssertEqual(CvType.CV_32FC3, _3dPoints.type()) |
||||
XCTAssertEqual(OpenCVTestCase.matSize, _3dPoints.rows()) |
||||
XCTAssertEqual(OpenCVTestCase.matSize, _3dPoints.cols()) |
||||
|
||||
truth = Mat(rows: OpenCVTestCase.matSize, cols: OpenCVTestCase.matSize, type: CvType.CV_32FC3) |
||||
|
||||
var _truth = [Float](repeating: 0.0, count: Int(OpenCVTestCase.matSize * OpenCVTestCase.matSize * 3)) |
||||
for i:Int in 0..<Int(OpenCVTestCase.matSize) { |
||||
for j:Int in 0..<Int(OpenCVTestCase.matSize) { |
||||
let start:Int = (i * Int(OpenCVTestCase.matSize) + j) * 3 |
||||
_truth[start + 0] = Float(i) |
||||
_truth[start + 1] = Float(j) |
||||
_truth[start + 2] = Float(i - j) |
||||
} |
||||
} |
||||
try truth!.put(row: 0, col: 0, data: _truth) |
||||
|
||||
try assertMatEqual(truth!, _3dPoints, OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
func testReprojectImageTo3DMatMatMatBoolean() throws { |
||||
let transformMatrix = Mat(rows: 4, cols: 4, type: CvType.CV_64F) |
||||
try transformMatrix.put(row: 0, col: 0, data: [0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] as [Double]) |
||||
|
||||
let disparity = Mat(rows: OpenCVTestCase.matSize, cols: OpenCVTestCase.matSize, type: CvType.CV_32F) |
||||
|
||||
var disp = [Float](repeating: 0.0, count: Int(OpenCVTestCase.matSize * OpenCVTestCase.matSize)) |
||||
for i in 0..<Int(OpenCVTestCase.matSize) { |
||||
for j in 0..<Int(OpenCVTestCase.matSize) { |
||||
disp[i * Int(OpenCVTestCase.matSize) + j] = Float(i - j) |
||||
} |
||||
} |
||||
disp[0] = -.greatestFiniteMagnitude |
||||
try disparity.put(row: 0, col: 0, data: disp) |
||||
|
||||
let _3dPoints = Mat() |
||||
|
||||
Calib3d.reprojectImageTo3D(disparity: disparity, _3dImage: _3dPoints, Q: transformMatrix, handleMissingValues: true) |
||||
|
||||
XCTAssertEqual(CvType.CV_32FC3, _3dPoints.type()) |
||||
XCTAssertEqual(OpenCVTestCase.matSize, _3dPoints.rows()) |
||||
XCTAssertEqual(OpenCVTestCase.matSize, _3dPoints.cols()) |
||||
|
||||
truth = Mat(rows: OpenCVTestCase.matSize, cols: OpenCVTestCase.matSize, type: CvType.CV_32FC3) |
||||
|
||||
var _truth = [Float](repeating: 0.0, count:Int(OpenCVTestCase.matSize * OpenCVTestCase.matSize * 3)) |
||||
for i in 0..<Int(OpenCVTestCase.matSize) { |
||||
for j in 0..<Int(OpenCVTestCase.matSize) { |
||||
_truth[(i * Int(OpenCVTestCase.matSize) + j) * 3 + 0] = Float(i) |
||||
_truth[(i * Int(OpenCVTestCase.matSize) + j) * 3 + 1] = Float(j) |
||||
_truth[(i * Int(OpenCVTestCase.matSize) + j) * 3 + 2] = Float(i - j) |
||||
} |
||||
} |
||||
_truth[2] = 10000 |
||||
try truth!.put(row: 0, col: 0, data: _truth) |
||||
|
||||
try assertMatEqual(truth!, _3dPoints, OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
func testReprojectImageTo3DMatMatMatBooleanInt() throws { |
||||
let transformMatrix = Mat(rows: 4, cols: 4, type: CvType.CV_64F) |
||||
try transformMatrix.put(row: 0, col: 0, data: [0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] as [Double]) |
||||
|
||||
let disparity = Mat(rows: OpenCVTestCase.matSize, cols: OpenCVTestCase.matSize, type: CvType.CV_32F) |
||||
|
||||
var disp = [Float](repeating: 0.0, count: Int(OpenCVTestCase.matSize * OpenCVTestCase.matSize)) |
||||
for i in 0..<Int(OpenCVTestCase.matSize) { |
||||
for j in 0..<Int(OpenCVTestCase.matSize) { |
||||
disp[i * Int(OpenCVTestCase.matSize) + j] = Float(i - j) |
||||
} |
||||
} |
||||
try disparity.put(row:0, col:0, data:disp) |
||||
|
||||
let _3dPoints = Mat() |
||||
|
||||
Calib3d.reprojectImageTo3D(disparity: disparity, _3dImage: _3dPoints, Q: transformMatrix, handleMissingValues: false, ddepth: CvType.CV_16S) |
||||
|
||||
XCTAssertEqual(CvType.CV_16SC3, _3dPoints.type()) |
||||
XCTAssertEqual(OpenCVTestCase.matSize, _3dPoints.rows()) |
||||
XCTAssertEqual(OpenCVTestCase.matSize, _3dPoints.cols()) |
||||
|
||||
truth = Mat(rows: OpenCVTestCase.matSize, cols: OpenCVTestCase.matSize, type: CvType.CV_16SC3) |
||||
|
||||
var _truth = [Int16](repeating: 0, count: Int(OpenCVTestCase.matSize * OpenCVTestCase.matSize * 3)) |
||||
for i in 0..<Int(OpenCVTestCase.matSize) { |
||||
for j in 0..<Int(OpenCVTestCase.matSize) { |
||||
let start = (i * Int(OpenCVTestCase.matSize) + j) * 3 |
||||
_truth[start + 0] = Int16(i) |
||||
_truth[start + 1] = Int16(j) |
||||
_truth[start + 2] = Int16(i - j) |
||||
} |
||||
} |
||||
try truth!.put(row: 0, col: 0, data: _truth) |
||||
|
||||
try assertMatEqual(truth!, _3dPoints, OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
func testRodriguesMatMat() throws { |
||||
let r = Mat(rows: 3, cols: 1, type: CvType.CV_32F) |
||||
let R = Mat(rows: 3, cols: 3, type: CvType.CV_32F) |
||||
|
||||
try r.put(row:0, col:0, data:[.pi, 0, 0] as [Float]) |
||||
|
||||
Calib3d.Rodrigues(src: r, dst: R) |
||||
|
||||
truth = Mat(rows: 3, cols: 3, type: CvType.CV_32F) |
||||
try truth!.put(row:0, col:0, data:[1, 0, 0, 0, -1, 0, 0, 0, -1] as [Float]) |
||||
try assertMatEqual(truth!, R, OpenCVTestCase.EPS) |
||||
|
||||
let r2 = Mat() |
||||
Calib3d.Rodrigues(src: R, dst: r2) |
||||
|
||||
try assertMatEqual(r, r2, OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
func testSolvePnPListOfPoint3ListOfPointMatMatMatMat() throws { |
||||
let intrinsics = Mat.eye(rows: 3, cols: 3, type: CvType.CV_64F) |
||||
try intrinsics.put(row: 0, col: 0, data: [400] as [Double]) |
||||
try intrinsics.put(row: 1, col: 1, data: [400] as [Double]) |
||||
try intrinsics.put(row: 0, col: 2, data: [640 / 2] as [Double]) |
||||
try intrinsics.put(row: 1, col: 2, data: [480 / 2] as [Double]) |
||||
|
||||
let minPnpPointsNum: Int32 = 4 |
||||
|
||||
let points3d = MatOfPoint3f() |
||||
points3d.alloc(minPnpPointsNum) |
||||
let points2d = MatOfPoint2f() |
||||
points2d.alloc(minPnpPointsNum) |
||||
|
||||
for i in 0..<minPnpPointsNum { |
||||
let x = Float.random(in: -50...50) |
||||
let y = Float.random(in: -50...50) |
||||
try points2d.put(row: i, col: 0, data: [x, y]) //add(Point(x, y)) |
||||
try points3d.put(row: i, col: 0, data: [0, y, x]) // add(Point3(0, y, x)) |
||||
} |
||||
|
||||
let rvec = Mat() |
||||
let tvec = Mat() |
||||
Calib3d.solvePnP(objectPoints: points3d, imagePoints: points2d, cameraMatrix: intrinsics, distCoeffs: MatOfDouble(), rvec: rvec, tvec: tvec) |
||||
|
||||
let truth_rvec = Mat(rows: 3, cols: 1, type: CvType.CV_64F) |
||||
try truth_rvec.put(row: 0, col: 0, data: [0, .pi / 2, 0] as [Double]) |
||||
|
||||
let truth_tvec = Mat(rows: 3, cols: 1, type: CvType.CV_64F) |
||||
try truth_tvec.put(row: 0, col: 0, data: [-320, -240, 400] as [Double]) |
||||
|
||||
try assertMatEqual(truth_rvec, rvec, OpenCVTestCase.EPS) |
||||
try assertMatEqual(truth_tvec, tvec, OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
func testComputeCorrespondEpilines() throws { |
||||
let fundamental = Mat(rows: 3, cols: 3, type: CvType.CV_64F) |
||||
try fundamental.put(row: 0, col: 0, data: [0, -0.577, 0.288, 0.577, 0, 0.288, -0.288, -0.288, 0]) |
||||
let left = MatOfPoint2f() |
||||
left.alloc(1) |
||||
try left.put(row: 0, col: 0, data: [2, 3] as [Float]) //add(Point(x, y)) |
||||
let lines = Mat() |
||||
let truth = Mat(rows: 1, cols: 1, type: CvType.CV_32FC3) |
||||
try truth.put(row: 0, col: 0, data: [-0.70735186, 0.70686162, -0.70588124]) |
||||
Calib3d.computeCorrespondEpilines(points: left, whichImage: 1, F: fundamental, lines: lines) |
||||
try assertMatEqual(truth, lines, OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
func testConstants() |
||||
{ |
||||
// calib3d.hpp: some constants have conflict with constants from 'fisheye' namespace |
||||
XCTAssertEqual(1, Calib3d.CALIB_USE_INTRINSIC_GUESS) |
||||
XCTAssertEqual(2, Calib3d.CALIB_FIX_ASPECT_RATIO) |
||||
XCTAssertEqual(4, Calib3d.CALIB_FIX_PRINCIPAL_POINT) |
||||
XCTAssertEqual(8, Calib3d.CALIB_ZERO_TANGENT_DIST) |
||||
XCTAssertEqual(16, Calib3d.CALIB_FIX_FOCAL_LENGTH) |
||||
XCTAssertEqual(32, Calib3d.CALIB_FIX_K1) |
||||
XCTAssertEqual(64, Calib3d.CALIB_FIX_K2) |
||||
XCTAssertEqual(128, Calib3d.CALIB_FIX_K3) |
||||
XCTAssertEqual(0x0800, Calib3d.CALIB_FIX_K4) |
||||
XCTAssertEqual(0x1000, Calib3d.CALIB_FIX_K5) |
||||
XCTAssertEqual(0x2000, Calib3d.CALIB_FIX_K6) |
||||
XCTAssertEqual(0x4000, Calib3d.CALIB_RATIONAL_MODEL) |
||||
XCTAssertEqual(0x8000, Calib3d.CALIB_THIN_PRISM_MODEL) |
||||
XCTAssertEqual(0x10000, Calib3d.CALIB_FIX_S1_S2_S3_S4) |
||||
XCTAssertEqual(0x40000, Calib3d.CALIB_TILTED_MODEL) |
||||
XCTAssertEqual(0x80000, Calib3d.CALIB_FIX_TAUX_TAUY) |
||||
XCTAssertEqual(0x100000, Calib3d.CALIB_USE_QR) |
||||
XCTAssertEqual(0x200000, Calib3d.CALIB_FIX_TANGENT_DIST) |
||||
XCTAssertEqual(0x100, Calib3d.CALIB_FIX_INTRINSIC) |
||||
XCTAssertEqual(0x200, Calib3d.CALIB_SAME_FOCAL_LENGTH) |
||||
XCTAssertEqual(0x400, Calib3d.CALIB_ZERO_DISPARITY) |
||||
XCTAssertEqual((1 << 17), Calib3d.CALIB_USE_LU) |
||||
XCTAssertEqual((1 << 22), Calib3d.CALIB_USE_EXTRINSIC_GUESS) |
||||
} |
||||
|
||||
func testSolvePnPGeneric_regression_16040() throws { |
||||
let intrinsics = Mat.eye(rows: 3, cols: 3, type: CvType.CV_64F) |
||||
try intrinsics.put(row: 0, col: 0, data: [400] as [Double]) |
||||
try intrinsics.put(row: 1, col: 1, data: [400] as [Double]) |
||||
try intrinsics.put(row: 0, col: 2, data: [640 / 2] as [Double]) |
||||
try intrinsics.put(row: 1, col: 2, data: [480 / 2] as [Double]) |
||||
|
||||
let minPnpPointsNum: Int32 = 4 |
||||
|
||||
let points3d = MatOfPoint3f() |
||||
points3d.alloc(minPnpPointsNum) |
||||
let points2d = MatOfPoint2f() |
||||
points2d.alloc(minPnpPointsNum) |
||||
|
||||
for i in 0..<minPnpPointsNum { |
||||
let x = Float.random(in: -50...50) |
||||
let y = Float.random(in: -50...50) |
||||
try points2d.put(row: i, col: 0, data: [x, y]) //add(Point(x, y)) |
||||
try points3d.put(row: i, col: 0, data: [0, y, x]) // add(Point3(0, y, x)) |
||||
} |
||||
|
||||
let rvecs = NSMutableArray() |
||||
let tvecs = NSMutableArray() |
||||
|
||||
let rvec = Mat() |
||||
let tvec = Mat() |
||||
|
||||
let reprojectionError = Mat(rows: 2, cols: 1, type: CvType.CV_64FC1) |
||||
|
||||
Calib3d.solvePnPGeneric(objectPoints: points3d, imagePoints: points2d, cameraMatrix: intrinsics, distCoeffs: MatOfDouble(), rvecs: rvecs, tvecs: tvecs, useExtrinsicGuess: false, flags: .SOLVEPNP_IPPE, rvec: rvec, tvec: tvec, reprojectionError: reprojectionError) |
||||
|
||||
let truth_rvec = Mat(rows: 3, cols: 1, type: CvType.CV_64F) |
||||
try truth_rvec.put(row: 0, col: 0, data: [0, .pi / 2, 0] as [Double]) |
||||
|
||||
let truth_tvec = Mat(rows: 3, cols: 1, type: CvType.CV_64F) |
||||
try truth_tvec.put(row: 0, col: 0, data: [-320, -240, 400] as [Double]) |
||||
|
||||
try assertMatEqual(truth_rvec, rvecs[0] as! Mat, 10 * OpenCVTestCase.EPS) |
||||
try assertMatEqual(truth_tvec, tvecs[0] as! Mat, 1000 * OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
func testGetDefaultNewCameraMatrixMat() { |
||||
let mtx = Calib3d.getDefaultNewCameraMatrix(cameraMatrix: gray0) |
||||
|
||||
XCTAssertFalse(mtx.empty()) |
||||
XCTAssertEqual(0, Core.countNonZero(src: mtx)) |
||||
} |
||||
|
||||
func testGetDefaultNewCameraMatrixMatSizeBoolean() { |
||||
let mtx = Calib3d.getDefaultNewCameraMatrix(cameraMatrix: gray0, imgsize: size, centerPrincipalPoint: true) |
||||
|
||||
XCTAssertFalse(mtx.empty()) |
||||
XCTAssertFalse(0 == Core.countNonZero(src: mtx)) |
||||
// TODO_: write better test |
||||
} |
||||
|
||||
func testUndistortMatMatMatMat() throws { |
||||
let src = Mat(rows: 3, cols: 3, type: CvType.CV_32F, scalar: Scalar(3)) |
||||
let cameraMatrix = Mat(rows: 3, cols: 3, type: CvType.CV_32F) |
||||
try cameraMatrix.put(row: 0, col: 0, data: [1, 0, 1] as [Float]) |
||||
try cameraMatrix.put(row: 1, col: 0, data: [0, 1, 2] as [Float]) |
||||
try cameraMatrix.put(row: 2, col: 0, data: [0, 0, 1] as [Float]) |
||||
|
||||
let distCoeffs = Mat(rows: 1, cols: 4, type: CvType.CV_32F) |
||||
try distCoeffs.put(row: 0, col: 0, data: [1, 3, 2, 4] as [Float]) |
||||
|
||||
Calib3d.undistort(src: src, dst: dst, cameraMatrix: cameraMatrix, distCoeffs: distCoeffs) |
||||
|
||||
truth = Mat(rows: 3, cols: 3, type: CvType.CV_32F) |
||||
try truth!.put(row: 0, col: 0, data: [0, 0, 0] as [Float]) |
||||
try truth!.put(row: 1, col: 0, data: [0, 0, 0] as [Float]) |
||||
try truth!.put(row: 2, col: 0, data: [0, 3, 0] as [Float]) |
||||
|
||||
try assertMatEqual(truth!, dst, OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
func testUndistortMatMatMatMatMat() throws { |
||||
let src = Mat(rows: 3, cols: 3, type: CvType.CV_32F, scalar: Scalar(3)) |
||||
let cameraMatrix = Mat(rows: 3, cols: 3, type: CvType.CV_32F) |
||||
try cameraMatrix.put(row: 0, col: 0, data: [1, 0, 1] as [Float]) |
||||
try cameraMatrix.put(row: 1, col: 0, data: [0, 1, 2] as [Float]) |
||||
try cameraMatrix.put(row: 2, col: 0, data: [0, 0, 1] as [Float]) |
||||
|
||||
let distCoeffs = Mat(rows: 1, cols: 4, type: CvType.CV_32F) |
||||
try distCoeffs.put(row: 0, col: 0, data: [2, 1, 4, 5] as [Float]) |
||||
|
||||
let newCameraMatrix = Mat(rows: 3, cols: 3, type: CvType.CV_32F, scalar: Scalar(1)) |
||||
|
||||
Calib3d.undistort(src: src, dst: dst, cameraMatrix: cameraMatrix, distCoeffs: distCoeffs, newCameraMatrix: newCameraMatrix) |
||||
|
||||
truth = Mat(rows: 3, cols: 3, type: CvType.CV_32F, scalar: Scalar(3)) |
||||
try assertMatEqual(truth!, dst, OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
//undistortPoints(List<Point> src, List<Point> dst, Mat cameraMatrix, Mat distCoeffs) |
||||
func testUndistortPointsListOfPointListOfPointMatMat() { |
||||
let src = MatOfPoint2f(array: [Point2f(x: 1, y: 2), Point2f(x: 3, y: 4), Point2f(x: -1, y: -1)]) |
||||
let dst = MatOfPoint2f() |
||||
let cameraMatrix = Mat.eye(rows: 3, cols: 3, type: CvType.CV_64FC1) |
||||
let distCoeffs = Mat(rows: 8, cols: 1, type: CvType.CV_64FC1, scalar: Scalar(0)) |
||||
|
||||
Calib3d.undistortPoints(src: src, dst: dst, cameraMatrix: cameraMatrix, distCoeffs: distCoeffs) |
||||
|
||||
XCTAssertEqual(src.toArray(), dst.toArray()) |
||||
} |
||||
} |
@ -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); |
@ -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; |
||||
} |
@ -0,0 +1,88 @@ |
||||
//
|
||||
// ByteVector.h
|
||||
//
|
||||
// Created by Giles Payne on 2020/01/04.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#import <Foundation/Foundation.h> |
||||
#ifdef __cplusplus |
||||
#import <vector> |
||||
#endif |
||||
|
||||
NS_ASSUME_NONNULL_BEGIN |
||||
|
||||
/**
|
||||
* Utility class to wrap a `std::vector<char>` |
||||
*/ |
||||
@interface ByteVector : NSObject |
||||
|
||||
#pragma mark - Constructors |
||||
|
||||
/**
|
||||
* Create ByteVector and initialize with the contents of an NSData object |
||||
* @param data NSData containing raw byte array |
||||
*/ |
||||
-(instancetype)initWithData:(NSData*)data; |
||||
|
||||
/**
|
||||
* Create ByteVector and initialize with the contents of another ByteVector object |
||||
* @param src ByteVector containing data to copy |
||||
*/ |
||||
-(instancetype)initWithVector:(ByteVector*)src; |
||||
|
||||
#ifdef __OBJC__ |
||||
/**
|
||||
* Create ByteVector from raw C array |
||||
* @param array The raw C array |
||||
* @elements elements The number of elements in the array |
||||
*/ |
||||
-(instancetype)initWithNativeArray:(char*)array elements:(NSInteger)elements; |
||||
#endif |
||||
|
||||
#ifdef __cplusplus |
||||
/**
|
||||
* Create ByteVector from std::vector<char> |
||||
* @param src The std::vector<char> object to wrap |
||||
*/ |
||||
-(instancetype)initWithStdVector:(std::vector<char>&)src; |
||||
+(instancetype)fromNative:(std::vector<char>&)src; |
||||
#endif |
||||
|
||||
#pragma mark - Properties |
||||
|
||||
/**
|
||||
* Length of the vector |
||||
*/ |
||||
@property(readonly) NSInteger length; |
||||
|
||||
#ifdef __OBJC__ |
||||
/**
|
||||
* Raw C array |
||||
*/ |
||||
@property(readonly) char* nativeArray; |
||||
#endif |
||||
|
||||
#ifdef __cplusplus |
||||
/**
|
||||
* The wrapped std::vector<char> object |
||||
*/ |
||||
@property(readonly) std::vector<char>& nativeRef; |
||||
#endif |
||||
|
||||
/**
|
||||
* NSData object containing the raw byte data |
||||
*/ |
||||
@property(readonly) NSData* data; |
||||
|
||||
#pragma mark - Accessor method |
||||
|
||||
/**
|
||||
* Return array element |
||||
* @param index Index of the array element to return |
||||
*/ |
||||
-(char)get:(NSInteger)index; |
||||
|
||||
@end |
||||
NS_ASSUME_NONNULL_END |
@ -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 |
@ -0,0 +1,53 @@ |
||||
// |
||||
// ByteVectorExt.swift |
||||
// |
||||
// Created by Giles Payne on 2020/01/04. |
||||
// |
||||
|
||||
import Foundation |
||||
|
||||
public extension ByteVector { |
||||
convenience init(_ array:[Int8]) { |
||||
let data = array.withUnsafeBufferPointer { Data(buffer: $0) } |
||||
self.init(data:data); |
||||
} |
||||
|
||||
subscript(index: Int) -> Int8 { |
||||
get { |
||||
return self.get(index) |
||||
} |
||||
} |
||||
|
||||
var array: [Int8] { |
||||
get { |
||||
var ret = Array<Int8>(repeating: 0, count: data.count/MemoryLayout<Int8>.stride) |
||||
_ = ret.withUnsafeMutableBytes { data.copyBytes(to: $0) } |
||||
return ret |
||||
} |
||||
} |
||||
} |
||||
|
||||
extension ByteVector : Sequence { |
||||
public typealias Iterator = ByteVectorIterator |
||||
public func makeIterator() -> ByteVectorIterator { |
||||
return ByteVectorIterator(self) |
||||
} |
||||
} |
||||
|
||||
public struct ByteVectorIterator: IteratorProtocol { |
||||
public typealias Element = Int8 |
||||
let byteVector: ByteVector |
||||
var pos = 0 |
||||
|
||||
init(_ byteVector: ByteVector) { |
||||
self.byteVector = byteVector |
||||
} |
||||
|
||||
mutating public func next() -> Int8? { |
||||
guard pos >= 0 && pos < byteVector.length |
||||
else { return nil } |
||||
|
||||
pos += 1 |
||||
return byteVector.get(pos - 1) |
||||
} |
||||
} |
@ -0,0 +1,85 @@ |
||||
//
|
||||
// CVObjcUtil.h
|
||||
//
|
||||
// Created by Giles Payne on 2020/01/02.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
typedef union { double d; int64_t l; } V64; |
||||
typedef union { float f; int32_t i; } V32; |
||||
|
||||
#define DOUBLE_TO_BITS(x) ((V64){ .d = x }).l |
||||
#define FLOAT_TO_BITS(x) ((V32){ .f = x }).i |
||||
|
||||
#ifdef __cplusplus |
||||
#import <vector> |
||||
|
||||
#define MAKE_PTR(t) (*((cv::Ptr<t>*)self.nativePtr)) |
||||
|
||||
template <typename CV, typename OBJC> std::vector<CV> objc2cv(NSArray<OBJC*>* _Nonnull array, CV& (* _Nonnull converter)(OBJC* _Nonnull)) { |
||||
std::vector<CV> ret; |
||||
for (OBJC* obj in array) { |
||||
ret.push_back(converter(obj)); |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
#define OBJC2CV(CV_CLASS, OBJC_CLASS, v, a) \ |
||||
std::vector<CV_CLASS> v = objc2cv<CV_CLASS, OBJC_CLASS>(a, [](OBJC_CLASS* objc) -> CV_CLASS& { return objc.nativeRef; }) |
||||
|
||||
#define OBJC2CV_CUSTOM(CV_CLASS, OBJC_CLASS, v, a, CONV) \ |
||||
std::vector<CV_CLASS> v; \
|
||||
for (OBJC_CLASS* obj in a) { \
|
||||
CV_CLASS tmp = CONV(obj); \
|
||||
v.push_back(tmp); \
|
||||
} |
||||
|
||||
template <typename CV, typename OBJC> void cv2objc(std::vector<CV>& vector, NSMutableArray<OBJC*>* _Nonnull array, OBJC* _Nonnull (* _Nonnull converter)(CV&)) { |
||||
[array removeAllObjects]; |
||||
for (size_t index = 0; index < vector.size(); index++) { |
||||
[array addObject:converter(vector[index])]; |
||||
} |
||||
} |
||||
|
||||
#define CV2OBJC(CV_CLASS, OBJC_CLASS, v, a) \ |
||||
cv2objc<CV_CLASS, OBJC_CLASS>(v, a, [](CV_CLASS& cv) -> OBJC_CLASS* { return [OBJC_CLASS fromNative:cv]; }) |
||||
|
||||
#define CV2OBJC_CUSTOM(CV_CLASS, OBJC_CLASS, v, a, UNCONV) \ |
||||
[a removeAllObjects]; \
|
||||
for (size_t index = 0; index < v.size(); index++) { \
|
||||
OBJC_CLASS *tmp = UNCONV(v[index]); \
|
||||
[a addObject:tmp]; \
|
||||
} |
||||
|
||||
template <typename CV, typename OBJC> std::vector<std::vector<CV>> objc2cv2(NSArray<NSArray<OBJC*>*>* _Nonnull array, CV& (* _Nonnull converter)(OBJC* _Nonnull)) { |
||||
std::vector<std::vector<CV>> ret; |
||||
for (NSArray<OBJC*>* innerArray in array) { |
||||
std::vector<CV> innerVector; |
||||
for (OBJC* obj in innerArray) { |
||||
innerVector.push_back(converter(obj)); |
||||
} |
||||
ret.push_back(innerVector); |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
#define OBJC2CV2(CV_CLASS, OBJC_CLASS, v, a) \ |
||||
std::vector<std::vector<CV_CLASS>> v = objc2cv2<CV_CLASS, OBJC_CLASS>(a, [](OBJC_CLASS* objc) -> CV_CLASS& { return objc.nativeRef; }) |
||||
|
||||
template <typename CV, typename OBJC> void cv2objc2(std::vector<std::vector<CV>>& vector, NSMutableArray<NSMutableArray<OBJC*>*>* _Nonnull array, OBJC* _Nonnull (* _Nonnull converter)(CV&)) { |
||||
[array removeAllObjects]; |
||||
for (size_t index = 0; index < vector.size(); index++) { |
||||
std::vector<CV>& innerVector = vector[index]; |
||||
NSMutableArray<OBJC*>* innerArray = [NSMutableArray arrayWithCapacity:innerVector.size()]; |
||||
for (size_t index2 = 0; index2 < innerVector.size(); index2++) { |
||||
[innerArray addObject:converter(innerVector[index2])]; |
||||
} |
||||
[array addObject:innerArray]; |
||||
} |
||||
} |
||||
|
||||
#define CV2OBJC2(CV_CLASS, OBJC_CLASS, v, a) \ |
||||
cv2objc2<CV_CLASS, OBJC_CLASS>(v, a, [](CV_CLASS& cv) -> OBJC_CLASS* { return [OBJC_CLASS fromNative:cv]; }) |
||||
|
||||
#endif |
@ -0,0 +1,98 @@ |
||||
//
|
||||
// Converters.h
|
||||
//
|
||||
// Created by Giles Payne on 2020/03/03.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import <opencv2/opencv.hpp> |
||||
#endif |
||||
|
||||
#import <Foundation/Foundation.h> |
||||
#import "Mat.h" |
||||
#import "CvType.h" |
||||
#import "Point2i.h" |
||||
#import "Point2f.h" |
||||
#import "Point2d.h" |
||||
#import "Point3i.h" |
||||
#import "Point3f.h" |
||||
#import "Point3d.h" |
||||
#import "Rect2i.h" |
||||
#import "Rect2d.h" |
||||
#import "KeyPoint.h" |
||||
#import "DMatch.h" |
||||
#import "RotatedRect.h" |
||||
|
||||
NS_ASSUME_NONNULL_BEGIN |
||||
|
||||
@interface Converters : NSObject |
||||
|
||||
+ (Mat*)vector_Point_to_Mat:(NSArray<Point2i*>*)pts NS_SWIFT_NAME(vector_Point_to_Mat(_:)); |
||||
|
||||
+ (NSArray<Point2i*>*)Mat_to_vector_Point:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_Point(_:)); |
||||
|
||||
+ (Mat*)vector_Point2f_to_Mat:(NSArray<Point2f*>*)pts NS_SWIFT_NAME(vector_Point2f_to_Mat(_:)); |
||||
|
||||
+ (NSArray<Point2f*>*)Mat_to_vector_Point2f:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_Point2f(_:)); |
||||
|
||||
+ (Mat*)vector_Point2d_to_Mat:(NSArray<Point2d*>*)pts NS_SWIFT_NAME(vector_Point2d_to_Mat(_:)); |
||||
|
||||
+ (NSArray<Point2f*>*)Mat_to_vector_Point2d:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_Point2d(_:)); |
||||
|
||||
+ (Mat*)vector_Point3i_to_Mat:(NSArray<Point3i*>*)pts NS_SWIFT_NAME(vector_Point3i_to_Mat(_:)); |
||||
|
||||
+ (NSArray<Point3i*>*)Mat_to_vector_Point3i:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_Point3i(_:)); |
||||
|
||||
+ (Mat*)vector_Point3f_to_Mat:(NSArray<Point3f*>*)pts NS_SWIFT_NAME(vector_Point3f_to_Mat(_:)); |
||||
|
||||
+ (NSArray<Point3f*>*)Mat_to_vector_Point3f:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_Point3f(_:)); |
||||
|
||||
+ (Mat*)vector_Point3d_to_Mat:(NSArray<Point3d*>*)pts NS_SWIFT_NAME(vector_Point3d_to_Mat(_:)); |
||||
|
||||
+ (NSArray<Point3d*>*)Mat_to_vector_Point3d:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_Point3d(_:)); |
||||
|
||||
+ (Mat*)vector_float_to_Mat:(NSArray<NSNumber*>*)fs NS_SWIFT_NAME(vector_float_to_Mat(_:)); |
||||
|
||||
+ (NSArray<NSNumber*>*)Mat_to_vector_float:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_float(_:)); |
||||
|
||||
+ (Mat*)vector_uchar_to_Mat:(NSArray<NSNumber*>*)us NS_SWIFT_NAME(vector_uchar_to_Mat(_:)); |
||||
|
||||
+ (NSArray<NSNumber*>*)Mat_to_vector_uchar:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_uchar(_:)); |
||||
|
||||
+ (Mat*)vector_char_to_Mat:(NSArray<NSNumber*>*)cs NS_SWIFT_NAME(vector_char_to_Mat(_:)); |
||||
|
||||
+ (NSArray<NSNumber*>*)Mat_to_vector_char:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_char(_:)); |
||||
|
||||
+ (Mat*)vector_int_to_Mat:(NSArray<NSNumber*>*)is NS_SWIFT_NAME(vector_int_to_Mat(_:)); |
||||
|
||||
+ (NSArray<NSNumber*>*)Mat_to_vector_int:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_int(_:)); |
||||
|
||||
+ (Mat*)vector_Rect_to_Mat:(NSArray<Rect2i*>*)rs NS_SWIFT_NAME(vector_Rect_to_Mat(_:)); |
||||
|
||||
+ (NSArray<Rect2i*>*)Mat_to_vector_Rect:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_Rect(_:)); |
||||
|
||||
+ (Mat*)vector_Rect2d_to_Mat:(NSArray<Rect2d*>*)rs NS_SWIFT_NAME(vector_Rect2d_to_Mat(_:)); |
||||
|
||||
+ (NSArray<Rect2d*>*)Mat_to_vector_Rect2d:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_Rect2d(_:)); |
||||
|
||||
+ (Mat*)vector_KeyPoint_to_Mat:(NSArray<KeyPoint*>*)kps NS_SWIFT_NAME(vector_KeyPoint_to_Mat(_:)); |
||||
|
||||
+ (NSArray<KeyPoint*>*)Mat_to_vector_KeyPoint:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_KeyPoint(_:)); |
||||
|
||||
+ (Mat*)vector_double_to_Mat:(NSArray<NSNumber*>*)ds NS_SWIFT_NAME(vector_double_to_Mat(_:)); |
||||
|
||||
+ (NSArray<NSNumber*>*)Mat_to_vector_double:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_double(_:)); |
||||
|
||||
+ (Mat*)vector_DMatch_to_Mat:(NSArray<DMatch*>*)matches NS_SWIFT_NAME(vector_DMatch_to_Mat(_:)); |
||||
|
||||
+ (NSArray<DMatch*>*)Mat_to_vector_DMatch:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_DMatch(_:)); |
||||
|
||||
+ (Mat*)vector_RotatedRect_to_Mat:(NSArray<RotatedRect*>*)rs NS_SWIFT_NAME(vector_RotatedRect_to_Mat(_:)); |
||||
|
||||
+ (NSArray<RotatedRect*>*)Mat_to_vector_RotatedRect:(Mat*)mat NS_SWIFT_NAME(Mat_to_vector_RotatedRect(_:)); |
||||
|
||||
@end |
||||
|
||||
NS_ASSUME_NONNULL_END |
@ -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 |
@ -0,0 +1,67 @@ |
||||
//
|
||||
// CvType.h
|
||||
//
|
||||
// Created by Giles Payne on 2019/10/13.
|
||||
//
|
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#endif |
||||
|
||||
#import <Foundation/Foundation.h> |
||||
|
||||
NS_ASSUME_NONNULL_BEGIN |
||||
|
||||
/**
|
||||
* Utility functions for handling CvType values |
||||
*/ |
||||
@interface CvType : NSObject |
||||
|
||||
#pragma mark - Type Utility functions |
||||
|
||||
/**
|
||||
* Create CvType value from depth and channel values |
||||
* @param depth Depth value. One of CV_8U, CV_8S, CV_16U, CV_16S, CV_32S, CV_32F or CV_64F |
||||
* @param channels Number of channels (from 1 to (CV_CN_MAX - 1)) |
||||
*/ |
||||
+ (int)makeType:(int)depth channels:(int)channels; |
||||
|
||||
/**
|
||||
* Get number of channels for type |
||||
* @param type Type value |
||||
*/ |
||||
+ (int)channels:(int)type; |
||||
|
||||
/**
|
||||
* Get depth for type |
||||
* @param type Type value |
||||
*/ |
||||
+ (int)depth:(int)type; |
||||
|
||||
/**
|
||||
* Get raw type size in bytes for type |
||||
* @param type Type value |
||||
*/ |
||||
+ (int)rawTypeSize:(int)type; |
||||
|
||||
/**
|
||||
* Returns true if the raw type is an integer type (if depth is CV_8U, CV_8S, CV_16U, CV_16S or CV_32S) |
||||
* @param type Type value |
||||
*/ |
||||
+ (BOOL)isInteger:(int)type; |
||||
|
||||
/**
|
||||
* Get element size in bytes for type |
||||
* @param type Type value |
||||
*/ |
||||
+ (int)ELEM_SIZE:(int)type NS_SWIFT_NAME(elemSize(_:)); |
||||
|
||||
/**
|
||||
* Get the string name for type |
||||
* @param type Type value |
||||
*/ |
||||
+ (NSString*)typeToString:(int)type; |
||||
|
||||
@end |
||||
|
||||
NS_ASSUME_NONNULL_END |
@ -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 |
@ -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) |
||||
} |
||||
} |
@ -0,0 +1,82 @@ |
||||
//
|
||||
// DMatch.h
|
||||
//
|
||||
// Created by Giles Payne on 2019/12/25.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#endif |
||||
|
||||
#import <Foundation/Foundation.h> |
||||
|
||||
NS_ASSUME_NONNULL_BEGIN |
||||
|
||||
/**
|
||||
* Structure for matching: query descriptor index, train descriptor index, train |
||||
* image index and distance between descriptors. |
||||
*/ |
||||
@interface DMatch : NSObject |
||||
|
||||
/**
|
||||
* Query descriptor index. |
||||
*/ |
||||
@property int queryIdx; |
||||
|
||||
/**
|
||||
* Train descriptor index. |
||||
*/ |
||||
@property int trainIdx; |
||||
|
||||
/**
|
||||
* Train image index. |
||||
*/ |
||||
@property int imgIdx; |
||||
|
||||
/**
|
||||
* Distance |
||||
*/ |
||||
@property float distance; |
||||
#ifdef __cplusplus |
||||
@property(readonly) cv::DMatch& nativeRef; |
||||
#endif |
||||
|
||||
- (instancetype)init; |
||||
- (instancetype)initWithQueryIdx:(int)queryIdx trainIdx:(int)trainIdx distance:(float)distance; |
||||
- (instancetype)initWithQueryIdx:(int)queryIdx trainIdx:(int)trainIdx imgIdx:(int)imgIdx distance:(float)distance; |
||||
#ifdef __cplusplus |
||||
+ (instancetype)fromNative:(cv::DMatch&)dMatch; |
||||
#endif |
||||
|
||||
/**
|
||||
* Distance comparison |
||||
* @param it DMatch object to compare |
||||
*/ |
||||
- (BOOL)lessThan:(DMatch*)it; |
||||
|
||||
/**
|
||||
* Clone object |
||||
*/ |
||||
- (DMatch*)clone; |
||||
|
||||
/**
|
||||
* Compare for equality |
||||
* @param other Object to compare |
||||
*/ |
||||
- (BOOL)isEqual:(nullable id)other; |
||||
|
||||
/**
|
||||
* Calculate hash for this object |
||||
*/ |
||||
- (NSUInteger)hash; |
||||
|
||||
/**
|
||||
* Returns a string that describes the contents of the object |
||||
*/ |
||||
- (NSString*)description; |
||||
|
||||
@end |
||||
|
||||
NS_ASSUME_NONNULL_END |
@ -0,0 +1,107 @@ |
||||
// |
||||
// DMatch.m |
||||
// |
||||
// Created by Giles Payne on 2019/12/25. |
||||
// |
||||
|
||||
#import "DMatch.h" |
||||
#import "CVObjcUtil.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; |
||||
} |
||||
} |
||||
|
||||
- (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 |
@ -0,0 +1,93 @@ |
||||
//
|
||||
// Double2.h
|
||||
//
|
||||
// Created by Giles Payne on 2020/05/22.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#endif |
||||
|
||||
#import <Foundation/Foundation.h> |
||||
|
||||
@class Mat; |
||||
|
||||
NS_ASSUME_NONNULL_BEGIN |
||||
|
||||
/**
|
||||
* Simple wrapper for a vector of two `double` |
||||
*/ |
||||
@interface Double2 : 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::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 |
@ -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 |
@ -0,0 +1,94 @@ |
||||
//
|
||||
// Double3.h
|
||||
//
|
||||
// Created by Giles Payne on 2020/05/22.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#endif |
||||
|
||||
#import <Foundation/Foundation.h> |
||||
|
||||
@class Mat; |
||||
|
||||
NS_ASSUME_NONNULL_BEGIN |
||||
|
||||
/**
|
||||
* Simple wrapper for a vector of three `double` |
||||
*/ |
||||
@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 |
@ -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 |
@ -0,0 +1,88 @@ |
||||
//
|
||||
// DoubleVector.h
|
||||
//
|
||||
// Created by Giles Payne on 2020/01/04.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#import <Foundation/Foundation.h> |
||||
#ifdef __cplusplus |
||||
#import <vector> |
||||
#endif |
||||
|
||||
NS_ASSUME_NONNULL_BEGIN |
||||
|
||||
/**
|
||||
* Utility class to wrap a `std::vector<double>` |
||||
*/ |
||||
@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 |
@ -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 |
@ -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) |
||||
} |
||||
} |
@ -0,0 +1,99 @@ |
||||
//
|
||||
// Float4.h
|
||||
//
|
||||
// Created by Giles Payne on 2020/02/05.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#endif |
||||
|
||||
#import <Foundation/Foundation.h> |
||||
|
||||
NS_ASSUME_NONNULL_BEGIN |
||||
|
||||
@class Mat; |
||||
|
||||
/**
|
||||
* Simple wrapper for a vector of four `float` |
||||
*/ |
||||
@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 |
@ -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 |
@ -0,0 +1,112 @@ |
||||
//
|
||||
// Float6.h
|
||||
//
|
||||
// Created by Giles Payne on 2020/02/05.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#endif |
||||
|
||||
#import <Foundation/Foundation.h> |
||||
|
||||
@class Mat; |
||||
|
||||
NS_ASSUME_NONNULL_BEGIN |
||||
|
||||
/**
|
||||
* Simple wrapper for a vector of six `float` |
||||
*/ |
||||
@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 |
@ -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]]]; |
||||
} |
||||
|
||||
- (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 |
@ -0,0 +1,88 @@ |
||||
//
|
||||
// FloatVector.h
|
||||
//
|
||||
// Created by Giles Payne on 2020/01/04.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#import <Foundation/Foundation.h> |
||||
#ifdef __cplusplus |
||||
#import <vector> |
||||
#endif |
||||
|
||||
NS_ASSUME_NONNULL_BEGIN |
||||
|
||||
/**
|
||||
* Utility class to wrap a `std::vector<float>` |
||||
*/ |
||||
@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 |
@ -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 |
@ -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) |
||||
} |
||||
} |
@ -0,0 +1,99 @@ |
||||
//
|
||||
// Int4.h
|
||||
//
|
||||
// Created by Giles Payne on 2020/02/05.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#endif |
||||
|
||||
#import <Foundation/Foundation.h> |
||||
|
||||
@class Mat; |
||||
|
||||
NS_ASSUME_NONNULL_BEGIN |
||||
|
||||
/**
|
||||
* Simple wrapper for a vector of four `int` |
||||
*/ |
||||
@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 |
@ -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 |
@ -0,0 +1,88 @@ |
||||
//
|
||||
// IntVector.h
|
||||
//
|
||||
// Created by Giles Payne on 2020/01/04.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#import <Foundation/Foundation.h> |
||||
#ifdef __cplusplus |
||||
#import <vector> |
||||
#endif |
||||
|
||||
NS_ASSUME_NONNULL_BEGIN |
||||
|
||||
/**
|
||||
* Utility class to wrap a `std::vector<int>` |
||||
*/ |
||||
@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 |
@ -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 |
@ -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) |
||||
} |
||||
} |
@ -0,0 +1,98 @@ |
||||
//
|
||||
// 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 |
@ -0,0 +1,95 @@ |
||||
// |
||||
// 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 |
@ -0,0 +1,157 @@ |
||||
//
|
||||
// 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 |
@ -0,0 +1,913 @@ |
||||
// |
||||
// 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" |
||||
|
||||
// return true if we have reached the final index |
||||
static bool incIdx(cv::Mat* mat, std::vector<int>& indices) { |
||||
for (int dim = mat->dims-1; dim>=0; dim--) { |
||||
indices[dim] = (indices[dim] + 1) % mat->size[dim]; |
||||
if (indices[dim] != 0) { |
||||
return false; |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
// returns true if final index was reached |
||||
static bool updateIdx(cv::Mat* mat, std::vector<int>& indices, int inc) { |
||||
for (int index = 0; index < inc; index++) { |
||||
if (incIdx(mat, indices)) { |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
@implementation Mat { |
||||
NSData* _nsdata; |
||||
} |
||||
|
||||
- (cv::Mat&)nativeRef { |
||||
return *(cv::Mat*)_nativePtr; |
||||
} |
||||
|
||||
- (instancetype)init { |
||||
self = [super init]; |
||||
if (self) { |
||||
_nativePtr = new cv::Mat(); |
||||
} |
||||
return self; |
||||
} |
||||
|
||||
- (void)dealloc { |
||||
if (_nativePtr != NULL) { |
||||
_nativePtr->release(); |
||||
delete _nativePtr; |
||||
} |
||||
_nsdata = NULL; |
||||
} |
||||
|
||||
- (instancetype)initWithNativeMat:(cv::Mat*)nativePtr { |
||||
self = [super init]; |
||||
if (self) { |
||||
_nativePtr = new cv::Mat(*nativePtr); |
||||
} |
||||
return self; |
||||
} |
||||
|
||||
+ (instancetype)fromNativePtr:(cv::Mat*)nativePtr { |
||||
return [[Mat alloc] initWithNativeMat:nativePtr]; |
||||
} |
||||
|
||||
+ (instancetype)fromNative:(cv::Mat&)nativeRef { |
||||
return [[Mat alloc] initWithNativeMat:&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))]; |
||||
} |
||||
|
||||
- (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*)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, ^char (int index) { return cv::saturate_cast<char>(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; |
||||
int matAvailable = getMatAvailable(mat, tempIndices); |
||||
int available = MIN(arrayAvailable, matAvailable); |
||||
int result = (int)(available * mat->elemSize() / mat->channels()); |
||||
if (mat->isContinuous()) { |
||||
memcpy(tBuffer, mat->ptr(tempIndices.data()), available * sizeof(T)); |
||||
} else { |
||||
int copyOffset = 0; |
||||
int copyCount = MIN((mat->size[mat->dims - 1] - tempIndices[mat->dims - 1]) * mat->channels(), available); |
||||
while (available > 0) { |
||||
memcpy(tBuffer + copyOffset, mat->ptr(tempIndices.data()), copyCount * sizeof(T)); |
||||
if (updateIdx(mat, tempIndices, copyCount / mat->channels())) { |
||||
break; |
||||
} |
||||
available -= copyCount; |
||||
copyOffset += copyCount * sizeof(T); |
||||
copyCount = MIN(mat->size[mat->dims-1] * mat->channels(), available); |
||||
} |
||||
} |
||||
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; |
||||
int matAvailable = getMatAvailable(mat, tempIndices); |
||||
int available = MIN(arrayAvailable, matAvailable); |
||||
int result = (int)(available * mat->elemSize() / mat->channels()); |
||||
if (mat->isContinuous()) { |
||||
memcpy(mat->ptr(tempIndices.data()), tBuffer, available * sizeof(T)); |
||||
} else { |
||||
int copyOffset = 0; |
||||
int copyCount = MIN((mat->size[mat->dims - 1] - tempIndices[mat->dims - 1]) * mat->channels(), available); |
||||
while (available > 0) { |
||||
memcpy(mat->ptr(tempIndices.data()), tBuffer + copyOffset, copyCount * sizeof(T)); |
||||
if (updateIdx(mat, tempIndices, copyCount / mat->channels())) { |
||||
break; |
||||
} |
||||
available -= copyCount; |
||||
copyOffset += copyCount * sizeof(T); |
||||
copyCount = MIN(mat->size[mat->dims-1] * (int)mat->channels(), available); |
||||
} |
||||
} |
||||
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 |
@ -0,0 +1,244 @@ |
||||
// |
||||
// 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] |
||||
} |
||||
} |
@ -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 |
||||
*/ |
||||
@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 |
@ -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 |
@ -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 |
||||
*/ |
||||
@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 |
@ -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 |
@ -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 |
||||
*/ |
||||
@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 |
@ -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 |
@ -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 |
||||
*/ |
||||
@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 |
@ -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 |
@ -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 |
||||
*/ |
||||
@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 |
@ -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 |
@ -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 |
||||
*/ |
||||
@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 |
@ -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 |
@ -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 |
||||
*/ |
||||
@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 |
@ -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 |
@ -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 |
||||
*/ |
||||
@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 |
@ -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 |
@ -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 |
||||
*/ |
||||
@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 |
@ -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 |
@ -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 |
||||
*/ |
||||
@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 |
@ -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 |
@ -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) |
||||
@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 |
@ -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 |
@ -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 |
||||
*/ |
||||
@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 |
@ -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 |
@ -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 |
||||
*/ |
||||
@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 |
@ -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 |
@ -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 |
||||
*/ |
||||
@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 |
@ -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 |
@ -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) |
||||
@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 |
@ -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 |
@ -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 |
||||
*/ |
||||
@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 |
@ -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 |
@ -0,0 +1,38 @@ |
||||
//
|
||||
// MinMaxLocResult.h
|
||||
//
|
||||
// Created by Giles Payne on 2019/12/28.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#endif |
||||
|
||||
#import <Foundation/Foundation.h> |
||||
|
||||
@class Point2i; |
||||
|
||||
NS_ASSUME_NONNULL_BEGIN |
||||
|
||||
/**
|
||||
* Result of operation to determine global minimum and maximum of an array |
||||
*/ |
||||
@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 |
@ -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 |
@ -0,0 +1,87 @@ |
||||
//
|
||||
// Point2d.h
|
||||
//
|
||||
// Created by Giles Payne on 2019/10/09.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#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` |
||||
*/ |
||||
@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 |
@ -0,0 +1,107 @@ |
||||
// |
||||
// Point2d.m |
||||
// |
||||
// Created by Giles Payne on 2019/10/09. |
||||
// |
||||
|
||||
#import "Point2d.h" |
||||
#import "Rect2d.h" |
||||
#import "CVObjcUtil.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]; |
||||
} |
||||
|
||||
- (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 |
@ -0,0 +1,87 @@ |
||||
//
|
||||
// Point2f.h
|
||||
//
|
||||
// Created by Giles Payne on 2019/10/09.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#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` |
||||
*/ |
||||
@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 |
@ -0,0 +1,105 @@ |
||||
// |
||||
// Point2f.m |
||||
// |
||||
// Created by Giles Payne on 2019/10/09. |
||||
// |
||||
|
||||
#import "Point2f.h" |
||||
#import "Rect2f.h" |
||||
#import "CVObjcUtil.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]; |
||||
} |
||||
|
||||
- (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 |
@ -0,0 +1,88 @@ |
||||
//
|
||||
// Point2i.h
|
||||
//
|
||||
// Created by Giles Payne on 2019/10/09.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#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` |
||||
*/ |
||||
NS_SWIFT_NAME(Point) |
||||
@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 |
@ -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 |
@ -0,0 +1,84 @@ |
||||
//
|
||||
// Point3d.h
|
||||
//
|
||||
// Created by Giles Payne on 2019/10/09.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#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` |
||||
*/ |
||||
@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; |
||||
|
||||
# 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 |
@ -0,0 +1,114 @@ |
||||
// |
||||
// Point3d.mm |
||||
// |
||||
// Created by Giles Payne on 2019/10/09. |
||||
// |
||||
|
||||
#import "Point3d.h" |
||||
#import "Point2d.h" |
||||
#import "CVObjcUtil.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; |
||||
} |
||||
|
||||
- (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; |
||||
} |
||||
} |
||||
|
||||
- (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 |
@ -0,0 +1,85 @@ |
||||
//
|
||||
// Point3f.h
|
||||
//
|
||||
// Created by Giles Payne on 2019/10/09.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#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` |
||||
*/ |
||||
@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; |
||||
|
||||
|
||||
# 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 |
@ -0,0 +1,111 @@ |
||||
// |
||||
// Point3f.mm |
||||
// |
||||
// Created by Giles Payne on 2019/10/09. |
||||
// |
||||
|
||||
#import "Point3f.h" |
||||
#import "Point2f.h" |
||||
#import "CVObjcUtil.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; |
||||
} |
||||
|
||||
- (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; |
||||
} |
||||
} |
||||
|
||||
- (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 |
@ -0,0 +1,84 @@ |
||||
//
|
||||
// Point3i.h
|
||||
//
|
||||
// Created by Giles Payne on 2019/10/09.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#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` |
||||
*/ |
||||
@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; |
||||
|
||||
# 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 |
@ -0,0 +1,111 @@ |
||||
// |
||||
// 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; |
||||
} |
||||
|
||||
- (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 |
@ -0,0 +1,93 @@ |
||||
//
|
||||
// Range.h
|
||||
//
|
||||
// Created by Giles Payne on 2019/10/08.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#endif |
||||
|
||||
#import <Foundation/Foundation.h> |
||||
|
||||
NS_ASSUME_NONNULL_BEGIN |
||||
|
||||
/**
|
||||
* Represents a range of dimension indices |
||||
*/ |
||||
@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 |
@ -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 |
@ -0,0 +1,111 @@ |
||||
//
|
||||
// Rect.h
|
||||
//
|
||||
// Created by Giles Payne on 2019/10/09.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#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` |
||||
*/ |
||||
@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 |
@ -0,0 +1,155 @@ |
||||
// |
||||
// Rect2d.mm |
||||
// |
||||
// Created by Giles Payne on 2019/10/09. |
||||
// |
||||
|
||||
#import "Rect2d.h" |
||||
#import "Point2d.h" |
||||
#import "Size2d.h" |
||||
#import "CVObjcUtil.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 { |
||||
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:(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; |
||||
} |
||||
} |
||||
|
||||
- (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 |
@ -0,0 +1,111 @@ |
||||
//
|
||||
// Rect.h
|
||||
//
|
||||
// Created by Giles Payne on 2019/10/09.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#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` |
||||
*/ |
||||
@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 |
@ -0,0 +1,151 @@ |
||||
// |
||||
// Rect2d.mm |
||||
// |
||||
// Created by Giles Payne on 2019/10/09. |
||||
// |
||||
|
||||
#import "Rect2f.h" |
||||
#import "Point2f.h" |
||||
#import "Size2f.h" |
||||
#import "CVObjcUtil.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 { |
||||
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:(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; |
||||
} |
||||
} |
||||
|
||||
- (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 |
@ -0,0 +1,112 @@ |
||||
//
|
||||
// Rect2i.h
|
||||
//
|
||||
// Created by Giles Payne on 2019/10/09.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#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` |
||||
*/ |
||||
NS_SWIFT_NAME(Rect) |
||||
@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 |
@ -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 |
@ -0,0 +1,86 @@ |
||||
//
|
||||
// RotatedRect.h
|
||||
//
|
||||
// Created by Giles Payne on 2019/12/26.
|
||||
//
|
||||
|
||||
#pragma once |
||||
|
||||
#ifdef __cplusplus |
||||
#import "opencv.hpp" |
||||
#endif |
||||
|
||||
@class Point2f; |
||||
@class Size2f; |
||||
@class Rect2f; |
||||
|
||||
#import <Foundation/Foundation.h> |
||||
|
||||
NS_ASSUME_NONNULL_BEGIN |
||||
|
||||
/**
|
||||
* Represents a rotated rectangle on a plane |
||||
*/ |
||||
@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 |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue