forked from hybridgroup/gocv
-
Notifications
You must be signed in to change notification settings - Fork 0
/
core.go
521 lines (435 loc) · 15.1 KB
/
core.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
package gocv
/*
#include <stdlib.h>
#include "core.h"
*/
import "C"
import (
"image"
"unsafe"
)
const (
// MatChannels1 is a single channel Mat.
MatChannels1 = 0
// MatChannels2 is 2 channel Mat.
MatChannels2 = 8
// MatChannels3 is 3 channel Mat.
MatChannels3 = 16
// MatChannels4 is 4 channel Mat.
MatChannels4 = 24
)
// MatType is the type for the various different kinds of Mat you can create.
type MatType int
const (
// MatTypeCV8U is a Mat of 8-bit unsigned int
MatTypeCV8U MatType = 0
// MatTypeCV8S is a Mat of 8-bit signed int
MatTypeCV8S = 1
// MatTypeCV16U is a Mat of 16-bit unsigned int
MatTypeCV16U = 2
// MatTypeCV16S is a Mat of 16-bit signed int
MatTypeCV16S = 3
// MatTypeCV32S is a Mat of 32-bit signed int
MatTypeCV32S = 4
// MatTypeCV32F is a Mat of 32-bit float
MatTypeCV32F = 5
// MatTypeCV64F is a Mat of 64-bit float
MatTypeCV64F = 6
// MatTypeCV8UC1 is a Mat of 8-bit unsigned int with a single channel
MatTypeCV8UC1 = MatTypeCV8U + MatChannels1
// MatTypeCV8UC2 is a Mat of 8-bit unsigned int with 2 channels
MatTypeCV8UC2 = MatTypeCV8U + MatChannels2
// MatTypeCV8UC3 is a Mat of 8-bit unsigned int with 3 channels
MatTypeCV8UC3 = MatTypeCV8U + MatChannels3
// MatTypeCV8UC4 is a Mat of 8-bit unsigned int with 4 channels
MatTypeCV8UC4 = MatTypeCV8U + MatChannels4
)
// Mat represents an n-dimensional dense numerical single-channel
// or multi-channel array. It can be used to store real or complex-valued
// vectors and matrices, grayscale or color images, voxel volumes,
// vector fields, point clouds, tensors, and histograms.
//
// For further details, please see:
// http://docs.opencv.org/3.4.0/d3/d63/classcv_1_1Mat.html
//
type Mat struct {
p C.Mat
}
// NewMat returns a new empty Mat.
func NewMat() Mat {
return Mat{p: C.Mat_New()}
}
// NewMatWithSize returns a new Mat with a specific size and type.
func NewMatWithSize(rows int, cols int, mt MatType) Mat {
return Mat{p: C.Mat_NewWithSize(C.int(rows), C.int(cols), C.int(mt))}
}
// NewMatFromScalar returns a new Mat for a specific Scalar value
func NewMatFromScalar(s Scalar, mt MatType) Mat {
sVal := C.struct_Scalar{
val1: C.double(s.Val1),
val2: C.double(s.Val2),
val3: C.double(s.Val3),
val4: C.double(s.Val4),
}
return Mat{p: C.Mat_NewFromScalar(sVal, C.int(mt))}
}
// Close the Mat object.
func (m *Mat) Close() error {
C.Mat_Close(m.p)
m.p = nil
return nil
}
// Ptr returns the Mat's underlying object pointer.
func (m *Mat) Ptr() C.Mat {
return m.p
}
// Empty determines if the Mat is empty or not.
func (m *Mat) Empty() bool {
isEmpty := C.Mat_Empty(m.p)
return isEmpty != 0
}
// Clone returns a cloned full copy of the Mat.
func (m *Mat) Clone() Mat {
return Mat{p: C.Mat_Clone(m.p)}
}
// CopyTo copies Mat into destination Mat.
func (m *Mat) CopyTo(dst Mat) {
C.Mat_CopyTo(m.p, dst.p)
return
}
// ToBytes copies the underlying Mat data to a byte array.
//
// For further details, please see:
// https://docs.opencv.org/3.3.1/d3/d63/classcv_1_1Mat.html#a4d33bed1c850265370d2af0ff02e1564
func (m *Mat) ToBytes() []byte {
b := C.Mat_ToBytes(m.p)
defer C.ByteArray_Release(b)
return toGoBytes(b)
}
// Region returns a new Mat that points to a region of this Mat. Changes made to the
// region Mat will affect the original Mat, since they are pointers to the underlying
// OpenCV Mat object.
func (m *Mat) Region(rio image.Rectangle) Mat {
cRect := C.struct_Rect{
x: C.int(rio.Min.X),
y: C.int(rio.Min.Y),
width: C.int(rio.Size().X),
height: C.int(rio.Size().Y),
}
return Mat{p: C.Mat_Region(m.p, cRect)}
}
// Reshape changes the shape and/or the number of channels of a 2D matrix without copying the data.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d3/d63/classcv_1_1Mat.html#a4eb96e3251417fa88b78e2abd6cfd7d8
//
func (m *Mat) Reshape(cn int, rows int) Mat {
return Mat{p: C.Mat_Reshape(m.p, C.int(cn), C.int(rows))}
}
// Mean calculates the mean value M of array elements, independently for each channel, and return it as Scalar
// TODO pass second paramter with mask
func (m *Mat) Mean() Scalar {
s := C.Mat_Mean(m.p)
return NewScalar(float64(s.val1), float64(s.val2), float64(s.val3), float64(s.val4))
}
// LUT performs a look-up table transform of an array.
//
// The function LUT fills the output array with values from the look-up table.
// Indices of the entries are taken from the input array.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d2/de8/group__core__array.html#gab55b8d062b7f5587720ede032d34156f
func LUT(src, wbLUT, dst Mat) {
C.LUT(src.p, wbLUT.p, dst.p)
}
// Rows returns the number of rows for this Mat.
func (m *Mat) Rows() int {
return int(C.Mat_Rows(m.p))
}
// Cols returns the number of columns for this Mat.
func (m *Mat) Cols() int {
return int(C.Mat_Cols(m.p))
}
// GetUCharAt returns a value from a specific row/col in this Mat expecting it to
// be of type uchar aka CV_8U.
func (m *Mat) GetUCharAt(row int, col int) int8 {
return int8(C.Mat_GetUChar(m.p, C.int(row), C.int(col)))
}
// GetSCharAt returns a value from a specific row/col in this Mat expecting it to
// be of type schar aka CV_8S.
func (m *Mat) GetSCharAt(row int, col int) int8 {
return int8(C.Mat_GetSChar(m.p, C.int(row), C.int(col)))
}
// GetShortAt returns a value from a specific row/col in this Mat expecting it to
// be of type short aka CV_16S.
func (m *Mat) GetShortAt(row int, col int) int16 {
return int16(C.Mat_GetShort(m.p, C.int(row), C.int(col)))
}
// GetIntAt returns a value from a specific row/col in this Mat expecting it to
// be of type int aka CV_32S.
func (m *Mat) GetIntAt(row int, col int) int32 {
return int32(C.Mat_GetInt(m.p, C.int(row), C.int(col)))
}
// GetFloatAt returns a value from a specific row/col in this Mat expecting it to
// be of type float aka CV_32F.
func (m *Mat) GetFloatAt(row int, col int) float32 {
return float32(C.Mat_GetFloat(m.p, C.int(row), C.int(col)))
}
// GetDoubleAt returns a value from a specific row/col in this Mat expecting it to
// be of type double aka CV_64F.
func (m *Mat) GetDoubleAt(row int, col int) float64 {
return float64(C.Mat_GetDouble(m.p, C.int(row), C.int(col)))
}
// SetUCharAt set a value from a specific row/col in this Mat expecting it to
// be of type uchar aka CV_8U.
func (m *Mat) SetUCharAt(row int, col int, val int8) {
C.Mat_SetUChar(m.p, C.int(row), C.int(col), C.uint8_t(val))
}
// SetSCharAt set a value from a specific row/col in this Mat expecting it to
// be of type schar aka CV_8S.
func (m *Mat) SetSCharAt(row int, col int, val int8) {
C.Mat_SetSChar(m.p, C.int(row), C.int(col), C.int8_t(val))
}
// SetShortAt set a value from a specific row/col in this Mat expecting it to
// be of type short aka CV_16S.
func (m *Mat) SetShortAt(row int, col int, val int16) {
C.Mat_SetShort(m.p, C.int(row), C.int(col), C.int16_t(val))
}
// SetIntAt set a value from a specific row/col in this Mat expecting it to
// be of type int aka CV_32S.
func (m *Mat) SetIntAt(row int, col int, val int32) {
C.Mat_SetInt(m.p, C.int(row), C.int(col), C.int32_t(val))
}
// SetFloatAt set a value from a specific row/col in this Mat expecting it to
// be of type float aka CV_32F.
func (m *Mat) SetFloatAt(row int, col int, val float32) {
C.Mat_SetFloat(m.p, C.int(row), C.int(col), C.float(val))
}
// SetDoubleAt set a value from a specific row/col in this Mat expecting it to
// be of type double aka CV_64F.
func (m *Mat) SetDoubleAt(row int, col int, val float64) {
C.Mat_SetDouble(m.p, C.int(row), C.int(col), C.double(val))
}
// AbsDiff calculates the per-element absolute difference between two arrays
// or between an array and a scalar.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d2/de8/group__core__array.html#ga6fef31bc8c4071cbc114a758a2b79c14
//
func AbsDiff(src1 Mat, src2 Mat, dst Mat) {
C.Mat_AbsDiff(src1.p, src2.p, dst.p)
}
// Add calculates the per-element sum of two arrays or an array and a scalar.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d2/de8/group__core__array.html#ga10ac1bfb180e2cfda1701d06c24fdbd6
//
func Add(src1 Mat, src2 Mat, dst Mat) {
C.Mat_Add(src1.p, src2.p, dst.p)
}
// AddWeighted calculates the weighted sum of two arrays.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d2/de8/group__core__array.html#gafafb2513349db3bcff51f54ee5592a19
//
func AddWeighted(src1 Mat, alpha float64, src2 Mat, beta float64, gamma float64, dst Mat) {
C.Mat_AddWeighted(src1.p, C.double(alpha),
src2.p, C.double(beta), C.double(gamma), dst.p)
}
// BitwiseAnd computes bitwise conjunction of the two arrays (dst = src1 & src2).
// Calculates the per-element bit-wise conjunction of two arrays
// or an array and a scalar.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d2/de8/group__core__array.html#ga60b4d04b251ba5eb1392c34425497e14
//
func BitwiseAnd(src1 Mat, src2 Mat, dst Mat) {
C.Mat_BitwiseAnd(src1.p, src2.p, dst.p)
}
// BitwiseNot inverts every bit of an array.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d2/de8/group__core__array.html#ga0002cf8b418479f4cb49a75442baee2f
//
func BitwiseNot(src1 Mat, dst Mat) {
C.Mat_BitwiseNot(src1.p, dst.p)
}
// BitwiseOr calculates the per-element bit-wise disjunction of two arrays
// or an array and a scalar.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d2/de8/group__core__array.html#gab85523db362a4e26ff0c703793a719b4
//
func BitwiseOr(src1 Mat, src2 Mat, dst Mat) {
C.Mat_BitwiseOr(src1.p, src2.p, dst.p)
}
// BitwiseXor calculates the per-element bit-wise "exclusive or" operation
// on two arrays or an array and a scalar.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d2/de8/group__core__array.html#ga84b2d8188ce506593dcc3f8cd00e8e2c
//
func BitwiseXor(src1 Mat, src2 Mat, dst Mat) {
C.Mat_BitwiseXor(src1.p, src2.p, dst.p)
}
// InRange checks if array elements lie between the elements of two Mat arrays.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d2/de8/group__core__array.html#ga48af0ab51e36436c5d04340e036ce981
//
func InRange(src Mat, lb Mat, ub Mat, dst Mat) {
C.Mat_InRange(src.p, lb.p, ub.p, dst.p)
}
// GetOptimalDFTSize returns the optimal Discrete Fourier Transform (DFT) size
// for a given vector size.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d2/de8/group__core__array.html#ga6577a2e59968936ae02eb2edde5de299
//
func GetOptimalDFTSize(vecsize int) int {
return int(C.Mat_GetOptimalDFTSize(C.int(vecsize)))
}
// DFT performs a forward or inverse Discrete Fourier Transform (DFT)
// of a 1D or 2D floating-point array.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d2/de8/group__core__array.html#gadd6cf9baf2b8b704a11b5f04aaf4f39d
//
func DFT(src Mat, dst Mat) {
C.Mat_DFT(src.p, dst.p)
}
// Merge creates one multi-channel array out of several single-channel ones.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d2/de8/group__core__array.html#ga7d7b4d6c6ee504b30a20b1680029c7b4
//
func Merge(mv []Mat, dst Mat) {
cMatArray := make([]C.Mat, len(mv))
for i, r := range mv {
cMatArray[i] = r.p
}
cMats := C.struct_Mats{
mats: (*C.Mat)(&cMatArray[0]),
length: C.int(len(mv)),
}
C.Mat_Merge(cMats, dst.p)
}
// MinMaxLoc finds the global minimum and maximum in an array.
//
// For further details, please see:
// https://docs.opencv.org/trunk/d2/de8/group__core__array.html#gab473bf2eb6d14ff97e89b355dac20707
//
func MinMaxLoc(input Mat) (minVal, maxVal float32, minLoc, maxLoc image.Point) {
var cMinVal C.double
var cMaxVal C.double
var cMinLoc C.struct_Point
var cMaxLoc C.struct_Point
C.Mat_MinMaxLoc(input.p, &cMinVal, &cMaxVal, &cMinLoc, &cMaxLoc)
minLoc = image.Pt(int(cMinLoc.x), int(cMinLoc.y))
maxLoc = image.Pt(int(cMaxLoc.x), int(cMaxLoc.y))
return float32(cMinVal), float32(cMaxVal), minLoc, maxLoc
}
// NormType for normalization operations.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d2/de8/group__core__array.html#gad12cefbcb5291cf958a85b4b67b6149f
//
type NormType int
const (
// NormInf indicates use infinite normalization.
NormInf NormType = 1
// NormL1 indicates use L1 normalization.
NormL1 = 2
// NormL2 indicates use L2 normalization.
NormL2 = 4
// NormL2Sqr indicates use L2 squared normalization.
NormL2Sqr = 5
// NormHamming indicates use Hamming normalization.
NormHamming = 6
// NormHamming2 indicates use Hamming 2-bit normalization.
NormHamming2 = 7
// NormTypeMask indicates use type mask for normalization.
NormTypeMask = 7
// NormRelative indicates use relative normalization.
NormRelative = 8
// NormMixMax indicates use min/max normalization.
NormMixMax = 32
)
// Normalize normalizes the norm or value range of an array.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d2/de8/group__core__array.html#ga87eef7ee3970f86906d69a92cbf064bd
//
func Normalize(src Mat, dst Mat, alpha float64, beta float64, typ NormType) {
C.Mat_Normalize(src.p, dst.p, C.double(alpha), C.double(beta), C.int(typ))
}
// Norm calculates the absolute norm of an array.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d2/de8/group__core__array.html#ga7c331fb8dd951707e184ef4e3f21dd33
//
func Norm(src1 Mat, normType NormType) float64 {
return float64(C.Norm(src1.p, C.int(normType)))
}
// TermCriteriaType for TermCriteria.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d9/d5d/classcv_1_1TermCriteria.html#a56fecdc291ccaba8aad27d67ccf72c57
//
type TermCriteriaType int
const (
// Count is the maximum number of iterations or elements to compute.
Count TermCriteriaType = 1
// MaxIter is the maximum number of iterations or elements to compute.
MaxIter = 1
// EPS is the desired accuracy or change in parameters at which the
// iterative algorithm stops.
EPS = 2
)
// TermCriteria is the criteria for iterative algorithms.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d9/d5d/classcv_1_1TermCriteria.html
//
type TermCriteria struct {
p C.TermCriteria
}
// NewTermCriteria returns a new TermCriteria.
func NewTermCriteria(typ TermCriteriaType, maxCount int, epsilon float64) TermCriteria {
return TermCriteria{p: C.TermCriteria_New(C.int(typ), C.int(maxCount), C.double(epsilon))}
}
// Scalar is a 4-element vector widely used in OpenCV to pass pixel values.
//
// For further details, please see:
// http://docs.opencv.org/3.4.0/d1/da0/classcv_1_1Scalar__.html
//
type Scalar struct {
Val1 float64
Val2 float64
Val3 float64
Val4 float64
}
// NewScalar returns a new Scalar. These are usually colors typically being in BGR order.
func NewScalar(v1 float64, v2 float64, v3 float64, v4 float64) Scalar {
s := Scalar{Val1: v1, Val2: v2, Val3: v3, Val4: v4}
return s
}
// KeyPoint is data structure for salient point detectors.
//
// For further details, please see:
// https://docs.opencv.org/3.4.0/d2/d29/classcv_1_1KeyPoint.html
//
type KeyPoint struct {
X, Y float64
Size, Angle, Response float64
Octave, ClassID int
}
func toByteArray(b []byte) C.struct_ByteArray {
return C.struct_ByteArray{
data: (*C.char)(unsafe.Pointer(&b[0])),
length: C.int(len(b)),
}
}
func toGoBytes(b C.struct_ByteArray) []byte {
return C.GoBytes(unsafe.Pointer(b.data), b.length)
}