Skip to content

Commit fe29bb8

Browse files
Merge pull request #644 from whwnsdlr1/add-accumulateWeighted
Add accumulate weighted
2 parents 756d64c + 0284d29 commit fe29bb8

File tree

6 files changed

+335
-0
lines changed

6 files changed

+335
-0
lines changed

cc/imgproc/imgproc.cc

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ NAN_MODULE_INIT(Imgproc::Init) {
5353
Nan::SetMethod(target, "gaussianBlurAsync", GaussianBlurAsync);
5454
Nan::SetMethod(target, "medianBlur", MedianBlur);
5555
Nan::SetMethod(target, "medianBlurAsync", MedianBlurAsync);
56+
Nan::SetMethod(target, "accumulate", Accumulate);
57+
Nan::SetMethod(target, "accumulateAsync", AccumulateAsync);
58+
Nan::SetMethod(target, "accumulateProduct", AccumulateProduct);
59+
Nan::SetMethod(target, "accumulateProductAsync", AccumulateProductAsync);
60+
Nan::SetMethod(target, "accumulateSquare", AccumulateSquare);
61+
Nan::SetMethod(target, "accumulateSquareAsync", AccumulateSquareAsync);
62+
Nan::SetMethod(target, "accumulateWeighted", AccumulateWeighted);
63+
Nan::SetMethod(target, "accumulateWeightedAsync", AccumulateWeightedAsync);
5664

5765

5866
Moments::Init(target);
@@ -391,4 +399,36 @@ NAN_METHOD(Imgproc::MedianBlurAsync) {
391399
FF::asyncBinding<ImgprocBindings::MedianBlur>("Imgproc", "MedianBlur", info);
392400
}
393401

402+
NAN_METHOD(Imgproc::Accumulate) {
403+
FF::syncBinding<ImgprocBindings::Accumulate>("Imgproc", "Accumulate", info);
404+
}
405+
406+
NAN_METHOD(Imgproc::AccumulateAsync) {
407+
FF::asyncBinding<ImgprocBindings::Accumulate>("Imgproc", "Accumulate", info);
408+
}
409+
410+
NAN_METHOD(Imgproc::AccumulateProduct) {
411+
FF::syncBinding<ImgprocBindings::AccumulateProduct>("Imgproc", "AccumulateProduct", info);
412+
}
413+
414+
NAN_METHOD(Imgproc::AccumulateProductAsync) {
415+
FF::asyncBinding<ImgprocBindings::AccumulateProduct>("Imgproc", "AccumulateProduct", info);
416+
}
417+
418+
NAN_METHOD(Imgproc::AccumulateSquare) {
419+
FF::syncBinding<ImgprocBindings::AccumulateSquare>("Imgproc", "AccumulateSquare", info);
420+
}
421+
422+
NAN_METHOD(Imgproc::AccumulateSquareAsync) {
423+
FF::asyncBinding<ImgprocBindings::AccumulateSquare>("Imgproc", "AccumulateSquare", info);
424+
}
425+
426+
NAN_METHOD(Imgproc::AccumulateWeighted) {
427+
FF::syncBinding<ImgprocBindings::AccumulateWeighted>("Imgproc", "AccumulateWeighted", info);
428+
}
429+
430+
NAN_METHOD(Imgproc::AccumulateWeightedAsync) {
431+
FF::asyncBinding<ImgprocBindings::AccumulateWeighted>("Imgproc", "AccumulateWeighted", info);
432+
}
433+
394434
#endif

cc/imgproc/imgproc.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ class Imgproc {
4141
static NAN_METHOD(GaussianBlurAsync);
4242
static NAN_METHOD(MedianBlur);
4343
static NAN_METHOD(MedianBlurAsync);
44+
static NAN_METHOD(Accumulate);
45+
static NAN_METHOD(AccumulateAsync);
46+
static NAN_METHOD(AccumulateProduct);
47+
static NAN_METHOD(AccumulateProductAsync);
48+
static NAN_METHOD(AccumulateSquare);
49+
static NAN_METHOD(AccumulateSquareAsync);
50+
static NAN_METHOD(AccumulateWeighted);
51+
static NAN_METHOD(AccumulateWeightedAsync);
4452
};
4553

4654
#endif

cc/imgproc/imgprocBindings.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,71 @@ namespace ImgprocBindings {
204204
};
205205
};
206206
};
207+
208+
class Accumulate : public CvBinding {
209+
public:
210+
void setup() {
211+
auto src = req<Mat::Converter>();
212+
auto dst = req<Mat::Converter>();
213+
auto mask = opt<Mat::Converter>("mask", cv::noArray().getMat());
214+
executeBinding = [=]() {
215+
auto depth = dst->ref().depth();
216+
if (depth != CV_32F && depth != CV_64F)
217+
throw std::runtime_error("dst must has a depth of CV_32F or CV_64F");
218+
cv::accumulate(src->ref(), dst->ref(), mask->ref());
219+
};
220+
};
221+
};
222+
223+
class AccumulateProduct : public CvBinding {
224+
public:
225+
void setup() {
226+
auto src1 = req<Mat::Converter>();
227+
auto src2 = req<Mat::Converter>();
228+
auto dst = req<Mat::Converter>();
229+
auto mask = opt<Mat::Converter>("mask", cv::noArray().getMat());
230+
231+
executeBinding = [=]() {
232+
auto depth = dst->ref().depth();
233+
if (depth != CV_32F && depth != CV_64F)
234+
throw std::runtime_error("dst must has a depth of CV_32F or CV_64F");
235+
cv::accumulateProduct(src1->ref(), src2->ref(), dst->ref(), mask->ref());
236+
};
237+
};
238+
};
239+
240+
class AccumulateSquare : public CvBinding {
241+
public:
242+
void setup() {
243+
auto src = req<Mat::Converter>();
244+
auto dst = req<Mat::Converter>();
245+
auto mask = opt<Mat::Converter>("mask", cv::noArray().getMat());
246+
247+
executeBinding = [=]() {
248+
auto depth = dst->ref().depth();
249+
if (depth != CV_32F && depth != CV_64F)
250+
throw std::runtime_error("dst must has a depth of CV_32F or CV_64F");
251+
cv::accumulateSquare(src->ref(), dst->ref(), mask->ref());
252+
};
253+
};
254+
};
255+
256+
class AccumulateWeighted : public CvBinding {
257+
public:
258+
void setup() {
259+
auto src = req<Mat::Converter>();
260+
auto dst = req<Mat::Converter>();
261+
auto alpha = req<FF::DoubleConverter>();
262+
auto mask = opt<Mat::Converter>("mask", cv::noArray().getMat());
263+
264+
executeBinding = [=]() {
265+
auto depth = dst->ref().depth();
266+
if (depth != CV_32F && depth != CV_64F)
267+
throw std::runtime_error("dst must has a depth of CV_32F or CV_64F");
268+
cv::accumulateWeighted(src->ref(), dst->ref(), alpha->ref(), mask->ref());
269+
};
270+
};
271+
};
207272
}
208273

209274
#endif

lib/typings/Mat.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ export class Mat {
3535
constructor(data: Buffer, rows: number, cols: number, type?: number);
3636
abs(): Mat;
3737
absdiff(otherMat: Mat): Mat;
38+
accumulate(src: Mat, mask?: Mat): Mat;
39+
accumulateAsync(src: Mat, mask?: Mat): Promise<Mat>;
40+
accumulateProduct(src1: Mat, src2: Mat, mask?: Mat): Mat;
41+
accumulateProductAsync(src1: Mat, src2:Mat, mask?: Mat): Promise<Mat>;
42+
accumulateSquare(src: Mat, mask?: Mat): Mat;
43+
accumulateSquareAsync(src: Mat, mask?: Mat): Promise<Mat>;
44+
accumulateWeighted(src: Mat, alpha: number, mask?: Mat): Mat;
45+
accumulateWeightedAsync(src: Mat, alpha: number, mask?: Mat): Promise<Mat>;
3846
adaptiveThreshold(maxVal: number, adaptiveMethod: number, thresholdType: number, blockSize: number, C: number): Mat;
3947
adaptiveThresholdAsync(maxVal: number, adaptiveMethod: number, thresholdType: number, blockSize: number, C: number): Promise<Mat>;
4048
add(otherMat: Mat): Mat;

lib/typings/cv.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ export interface HistAxes {
1919
ranges: number[];
2020
}
2121

22+
export function accumulate(src: Mat, dst: Mat, mask?: Mat): void;
23+
export function accumulateAsync(src: Mat, dst: Mat, mask?: Mat): Promise<void>;
24+
export function accumulateProduct(src1: Mat, src2: Mat, dst: Mat, mask?: Mat): void;
25+
export function accumulateProductAsync(src1: Mat, src2: Mat, dst:Mat, mask?: Mat): Promise<void>;
26+
export function accumulateSquare(src: Mat, dst: Mat, mask?: Mat): void;
27+
export function accumulateSquareAsync(src: Mat, dst: Mat, mask?: Mat): Promise<void>;
28+
export function accumulateWeighted(src: Mat, dst: Mat, alpha: number, mask?: Mat): void;
29+
export function accumulateWeightedAsync(src: Mat, dst: Mat, alpha: number, mask?: Mat): Promise<void>;
2230
export function addWeighted(mat: Mat, alpha: number, mat2: Mat, beta: number, gamma: number, dtype?: number): Mat;
2331
export function addWeightedAsync(mat: Mat, alpha: number, mat2: Mat, beta: number, gamma: number, dtype?: number): Promise<Mat>;
2432
export function applyColorMap(src: Mat, colormap: number | Mat): Mat;

test/tests/imgproc/imgprocTests.js

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,4 +397,210 @@ module.exports = ({ cv, utils, getTestImg }) => {
397397
}
398398
});
399399

400+
describe('accumulate', () => {
401+
const srcData = [
402+
[[1, 2, 3], [4, 5, 6]],
403+
[[7, 8, 9], [10, 11, 12]]
404+
]
405+
const dstData = [
406+
[[1, 1, 1], [1, 1, 1]],
407+
[[1, 1, 1], [1, 1, 1]]
408+
]
409+
const maskData = [
410+
[255, 0],
411+
[0, 255]
412+
]
413+
const expectedData = [
414+
[[2, 3, 4], [1, 1, 1]],
415+
[[1, 1, 1], [11, 12, 13]]
416+
]
417+
const src = new cv.Mat(srcData, cv.CV_8UC3)
418+
const dstDepth8 = new cv.Mat(dstData, cv.CV_8UC3)
419+
let dst
420+
const mask = new cv.Mat(maskData, cv.CV_8UC1)
421+
422+
it('should throw if dst has not a depth of CV_32F or CV_64F', () => {
423+
expect(() => cv.accumulate(src, dstDepth8)).to.throw('Imgproc::Accumulate - dst must has a depth of CV_32F or CV_64F');
424+
});
425+
426+
generateAPITests({
427+
getDut: () => cv,
428+
methodName: 'accumulate',
429+
methodNameSpace: 'Imgproc',
430+
beforeHook: () => dst = new cv.Mat(dstData, cv.CV_32FC3),
431+
getRequiredArgs: () => ([
432+
src,
433+
dst,
434+
mask
435+
]),
436+
expectOutput: () => {
437+
channelIndices = ['x', 'y', 'z']
438+
for (let row = 0; row < dst.rows; row++) {
439+
for (let col = 0; col < dst.cols; col++) {
440+
for (let channel = 0; channel < dst.channels; channel++) {
441+
expect(dst.at(row, col)[channelIndices[channel]]).to.be.closeTo(expectedData[row][col][channel], 1e-5);
442+
}
443+
}
444+
}
445+
}
446+
});
447+
});
448+
449+
describe('accumulateProduct', () => {
450+
const srcData1 = [
451+
[[1, 2, 3], [4, 5, 6]],
452+
[[7, 8, 9], [10, 11, 12]]
453+
]
454+
const srcData2 = [
455+
[[2, 2, 2], [2, 2, 2]],
456+
[[2, 2, 2], [2, 2, 2]]
457+
]
458+
const dstData = [
459+
[[1, 1, 1], [1, 1, 1]],
460+
[[1, 1, 1], [1, 1, 1]]
461+
]
462+
const maskData = [
463+
[255, 0],
464+
[0, 255]
465+
]
466+
const expectedData = [
467+
[[3, 5, 7], [1, 1, 1]],
468+
[[1, 1, 1], [21, 23, 25]]
469+
]
470+
471+
const src1 = new cv.Mat(srcData1, cv.CV_8UC3)
472+
const src2 = new cv.Mat(srcData2, cv.CV_8UC3)
473+
let dst
474+
const dstDepth8 = new cv.Mat(dstData, cv.CV_8UC3)
475+
const mask = new cv.Mat(maskData, cv.CV_8UC1)
476+
477+
it('should throw if dst has not a depth of CV_32F or CV_64F', () => {
478+
expect(() => cv.accumulateProduct(src1, src2, dstDepth8)).to.throw('Imgproc::AccumulateProduct - dst must has a depth of CV_32F or CV_64F');
479+
});
480+
481+
generateAPITests({
482+
getDut: () => cv,
483+
methodName: 'accumulateProduct',
484+
methodNameSpace: 'Imgproc',
485+
beforeHook: () => dst = new cv.Mat(dstData, cv.CV_32FC3),
486+
getRequiredArgs: () => ([
487+
src1,
488+
src2,
489+
dst,
490+
mask
491+
]),
492+
expectOutput: () => {
493+
channelIndices = ['x', 'y', 'z']
494+
for (let row = 0; row < dst.rows; row++) {
495+
for (let col = 0; col < dst.cols; col++) {
496+
for (let channel = 0; channel < dst.channels; channel++) {
497+
expect(dst.at(row, col)[channelIndices[channel]]).to.be.closeTo(expectedData[row][col][channel], 1e-5);
498+
}
499+
}
500+
}
501+
}
502+
});
503+
});
504+
505+
describe('accumulateSquare', () => {
506+
const srcData = [
507+
[[1, 2, 3], [4, 5, 6]],
508+
[[7, 8, 9], [10, 11, 12]]
509+
]
510+
const dstData = [
511+
[[1, 1, 1], [1, 1, 1]],
512+
[[1, 1, 1], [1, 1, 1]]
513+
]
514+
const maskData = [
515+
[255, 0],
516+
[0, 255]
517+
]
518+
const expectedData = [
519+
[[2, 5, 10], [1, 1, 1]],
520+
[[1, 1, 1], [101, 122, 145]]
521+
]
522+
523+
const src = new cv.Mat(srcData, cv.CV_8UC3)
524+
let dst
525+
const dstDepth8 = new cv.Mat(dstData, cv.CV_8UC3)
526+
const mask = new cv.Mat(maskData, cv.CV_8UC1)
527+
528+
it('should throw if dst has not a depth of CV_32F or CV_64F', () => {
529+
expect(() => cv.accumulateSquare(src, dstDepth8)).to.throw('Imgproc::AccumulateSquare - dst must has a depth of CV_32F or CV_64F');
530+
});
531+
532+
generateAPITests({
533+
getDut: () => cv,
534+
methodName: 'accumulateSquare',
535+
methodNameSpace: 'Imgproc',
536+
beforeHook: () => dst = new cv.Mat(dstData, cv.CV_32FC3),
537+
getRequiredArgs: () => ([
538+
src,
539+
dst,
540+
mask
541+
]),
542+
expectOutput: () => {
543+
channelIndices = ['x', 'y', 'z']
544+
for (let row = 0; row < dst.rows; row++) {
545+
for (let col = 0; col < dst.cols; col++) {
546+
for (let channel = 0; channel < dst.channels; channel++) {
547+
expect(dst.at(row, col)[channelIndices[channel]]).to.be.closeTo(expectedData[row][col][channel], 1e-5);
548+
}
549+
}
550+
}
551+
}
552+
});
553+
});
554+
555+
describe('accumulateWeighted', () => {
556+
const srcData = [
557+
[[1, 2, 3], [4, 5, 6]],
558+
[[7, 8, 9], [10, 11, 12]]
559+
]
560+
const dstData = [
561+
[[1, 1, 1], [1, 1, 1]],
562+
[[1, 1, 1], [1, 1, 1]]
563+
]
564+
const alpha = 0.7
565+
const maskData = [
566+
[255, 0],
567+
[0, 255]
568+
]
569+
const expectedData = [
570+
[[(1 - alpha) * 1 + alpha * 1, (1 - alpha) * 1 + alpha * 2, (1 - alpha) * 1 + alpha * 3], [1, 1, 1]],
571+
[[1, 1, 1], [(1 - alpha) * 1 + alpha * 10, (1 - alpha) * 1 + alpha * 11, (1 - alpha) * 1 + alpha * 12]]
572+
]
573+
574+
const src = new cv.Mat(srcData, cv.CV_8UC3)
575+
let dst
576+
const dstDepth8 = new cv.Mat(dstData, cv.CV_8UC3)
577+
const mask = new cv.Mat(maskData, cv.CV_8UC1)
578+
579+
it('should throw if dst has not a depth of CV_32F or CV_64F', () => {
580+
expect(() => cv.accumulateWeighted(src, dstDepth8, alpha)).to.throw('Imgproc::AccumulateWeighted - dst must has a depth of CV_32F or CV_64F');
581+
});
582+
583+
generateAPITests({
584+
getDut: () => cv,
585+
methodName: 'accumulateWeighted',
586+
methodNameSpace: 'Imgproc',
587+
beforeHook: () => dst = new cv.Mat(dstData, cv.CV_32FC3),
588+
getRequiredArgs: () => ([
589+
src,
590+
dst,
591+
alpha,
592+
mask
593+
]),
594+
expectOutput: () => {
595+
channelIndices = ['x', 'y', 'z']
596+
for (let row = 0; row < dst.rows; row++) {
597+
for (let col = 0; col < dst.cols; col++) {
598+
for (let channel = 0; channel < dst.channels; channel++) {
599+
expect(dst.at(row, col)[channelIndices[channel]]).to.be.closeTo(expectedData[row][col][channel], 1e-5);
600+
}
601+
}
602+
}
603+
}
604+
});
605+
});
400606
};

0 commit comments

Comments
 (0)