Skip to content

Commit

Permalink
Merge pull request #644 from whwnsdlr1/add-accumulateWeighted
Browse files Browse the repository at this point in the history
Add accumulate weighted
  • Loading branch information
justadudewhohacks authored Oct 18, 2019
2 parents 756d64c + 0284d29 commit fe29bb8
Show file tree
Hide file tree
Showing 6 changed files with 335 additions and 0 deletions.
40 changes: 40 additions & 0 deletions cc/imgproc/imgproc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ NAN_MODULE_INIT(Imgproc::Init) {
Nan::SetMethod(target, "gaussianBlurAsync", GaussianBlurAsync);
Nan::SetMethod(target, "medianBlur", MedianBlur);
Nan::SetMethod(target, "medianBlurAsync", MedianBlurAsync);
Nan::SetMethod(target, "accumulate", Accumulate);
Nan::SetMethod(target, "accumulateAsync", AccumulateAsync);
Nan::SetMethod(target, "accumulateProduct", AccumulateProduct);
Nan::SetMethod(target, "accumulateProductAsync", AccumulateProductAsync);
Nan::SetMethod(target, "accumulateSquare", AccumulateSquare);
Nan::SetMethod(target, "accumulateSquareAsync", AccumulateSquareAsync);
Nan::SetMethod(target, "accumulateWeighted", AccumulateWeighted);
Nan::SetMethod(target, "accumulateWeightedAsync", AccumulateWeightedAsync);


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

NAN_METHOD(Imgproc::Accumulate) {
FF::syncBinding<ImgprocBindings::Accumulate>("Imgproc", "Accumulate", info);
}

NAN_METHOD(Imgproc::AccumulateAsync) {
FF::asyncBinding<ImgprocBindings::Accumulate>("Imgproc", "Accumulate", info);
}

NAN_METHOD(Imgproc::AccumulateProduct) {
FF::syncBinding<ImgprocBindings::AccumulateProduct>("Imgproc", "AccumulateProduct", info);
}

NAN_METHOD(Imgproc::AccumulateProductAsync) {
FF::asyncBinding<ImgprocBindings::AccumulateProduct>("Imgproc", "AccumulateProduct", info);
}

NAN_METHOD(Imgproc::AccumulateSquare) {
FF::syncBinding<ImgprocBindings::AccumulateSquare>("Imgproc", "AccumulateSquare", info);
}

NAN_METHOD(Imgproc::AccumulateSquareAsync) {
FF::asyncBinding<ImgprocBindings::AccumulateSquare>("Imgproc", "AccumulateSquare", info);
}

NAN_METHOD(Imgproc::AccumulateWeighted) {
FF::syncBinding<ImgprocBindings::AccumulateWeighted>("Imgproc", "AccumulateWeighted", info);
}

NAN_METHOD(Imgproc::AccumulateWeightedAsync) {
FF::asyncBinding<ImgprocBindings::AccumulateWeighted>("Imgproc", "AccumulateWeighted", info);
}

#endif
8 changes: 8 additions & 0 deletions cc/imgproc/imgproc.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ class Imgproc {
static NAN_METHOD(GaussianBlurAsync);
static NAN_METHOD(MedianBlur);
static NAN_METHOD(MedianBlurAsync);
static NAN_METHOD(Accumulate);
static NAN_METHOD(AccumulateAsync);
static NAN_METHOD(AccumulateProduct);
static NAN_METHOD(AccumulateProductAsync);
static NAN_METHOD(AccumulateSquare);
static NAN_METHOD(AccumulateSquareAsync);
static NAN_METHOD(AccumulateWeighted);
static NAN_METHOD(AccumulateWeightedAsync);
};

#endif
65 changes: 65 additions & 0 deletions cc/imgproc/imgprocBindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,71 @@ namespace ImgprocBindings {
};
};
};

class Accumulate : public CvBinding {
public:
void setup() {
auto src = req<Mat::Converter>();
auto dst = req<Mat::Converter>();
auto mask = opt<Mat::Converter>("mask", cv::noArray().getMat());
executeBinding = [=]() {
auto depth = dst->ref().depth();
if (depth != CV_32F && depth != CV_64F)
throw std::runtime_error("dst must has a depth of CV_32F or CV_64F");
cv::accumulate(src->ref(), dst->ref(), mask->ref());
};
};
};

class AccumulateProduct : public CvBinding {
public:
void setup() {
auto src1 = req<Mat::Converter>();
auto src2 = req<Mat::Converter>();
auto dst = req<Mat::Converter>();
auto mask = opt<Mat::Converter>("mask", cv::noArray().getMat());

executeBinding = [=]() {
auto depth = dst->ref().depth();
if (depth != CV_32F && depth != CV_64F)
throw std::runtime_error("dst must has a depth of CV_32F or CV_64F");
cv::accumulateProduct(src1->ref(), src2->ref(), dst->ref(), mask->ref());
};
};
};

class AccumulateSquare : public CvBinding {
public:
void setup() {
auto src = req<Mat::Converter>();
auto dst = req<Mat::Converter>();
auto mask = opt<Mat::Converter>("mask", cv::noArray().getMat());

executeBinding = [=]() {
auto depth = dst->ref().depth();
if (depth != CV_32F && depth != CV_64F)
throw std::runtime_error("dst must has a depth of CV_32F or CV_64F");
cv::accumulateSquare(src->ref(), dst->ref(), mask->ref());
};
};
};

class AccumulateWeighted : public CvBinding {
public:
void setup() {
auto src = req<Mat::Converter>();
auto dst = req<Mat::Converter>();
auto alpha = req<FF::DoubleConverter>();
auto mask = opt<Mat::Converter>("mask", cv::noArray().getMat());

executeBinding = [=]() {
auto depth = dst->ref().depth();
if (depth != CV_32F && depth != CV_64F)
throw std::runtime_error("dst must has a depth of CV_32F or CV_64F");
cv::accumulateWeighted(src->ref(), dst->ref(), alpha->ref(), mask->ref());
};
};
};
}

#endif
8 changes: 8 additions & 0 deletions lib/typings/Mat.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ export class Mat {
constructor(data: Buffer, rows: number, cols: number, type?: number);
abs(): Mat;
absdiff(otherMat: Mat): Mat;
accumulate(src: Mat, mask?: Mat): Mat;
accumulateAsync(src: Mat, mask?: Mat): Promise<Mat>;
accumulateProduct(src1: Mat, src2: Mat, mask?: Mat): Mat;
accumulateProductAsync(src1: Mat, src2:Mat, mask?: Mat): Promise<Mat>;
accumulateSquare(src: Mat, mask?: Mat): Mat;
accumulateSquareAsync(src: Mat, mask?: Mat): Promise<Mat>;
accumulateWeighted(src: Mat, alpha: number, mask?: Mat): Mat;
accumulateWeightedAsync(src: Mat, alpha: number, mask?: Mat): Promise<Mat>;
adaptiveThreshold(maxVal: number, adaptiveMethod: number, thresholdType: number, blockSize: number, C: number): Mat;
adaptiveThresholdAsync(maxVal: number, adaptiveMethod: number, thresholdType: number, blockSize: number, C: number): Promise<Mat>;
add(otherMat: Mat): Mat;
Expand Down
8 changes: 8 additions & 0 deletions lib/typings/cv.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ export interface HistAxes {
ranges: number[];
}

export function accumulate(src: Mat, dst: Mat, mask?: Mat): void;
export function accumulateAsync(src: Mat, dst: Mat, mask?: Mat): Promise<void>;
export function accumulateProduct(src1: Mat, src2: Mat, dst: Mat, mask?: Mat): void;
export function accumulateProductAsync(src1: Mat, src2: Mat, dst:Mat, mask?: Mat): Promise<void>;
export function accumulateSquare(src: Mat, dst: Mat, mask?: Mat): void;
export function accumulateSquareAsync(src: Mat, dst: Mat, mask?: Mat): Promise<void>;
export function accumulateWeighted(src: Mat, dst: Mat, alpha: number, mask?: Mat): void;
export function accumulateWeightedAsync(src: Mat, dst: Mat, alpha: number, mask?: Mat): Promise<void>;
export function addWeighted(mat: Mat, alpha: number, mat2: Mat, beta: number, gamma: number, dtype?: number): Mat;
export function addWeightedAsync(mat: Mat, alpha: number, mat2: Mat, beta: number, gamma: number, dtype?: number): Promise<Mat>;
export function applyColorMap(src: Mat, colormap: number | Mat): Mat;
Expand Down
206 changes: 206 additions & 0 deletions test/tests/imgproc/imgprocTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -397,4 +397,210 @@ module.exports = ({ cv, utils, getTestImg }) => {
}
});

describe('accumulate', () => {
const srcData = [
[[1, 2, 3], [4, 5, 6]],
[[7, 8, 9], [10, 11, 12]]
]
const dstData = [
[[1, 1, 1], [1, 1, 1]],
[[1, 1, 1], [1, 1, 1]]
]
const maskData = [
[255, 0],
[0, 255]
]
const expectedData = [
[[2, 3, 4], [1, 1, 1]],
[[1, 1, 1], [11, 12, 13]]
]
const src = new cv.Mat(srcData, cv.CV_8UC3)
const dstDepth8 = new cv.Mat(dstData, cv.CV_8UC3)
let dst
const mask = new cv.Mat(maskData, cv.CV_8UC1)

it('should throw if dst has not a depth of CV_32F or CV_64F', () => {
expect(() => cv.accumulate(src, dstDepth8)).to.throw('Imgproc::Accumulate - dst must has a depth of CV_32F or CV_64F');
});

generateAPITests({
getDut: () => cv,
methodName: 'accumulate',
methodNameSpace: 'Imgproc',
beforeHook: () => dst = new cv.Mat(dstData, cv.CV_32FC3),
getRequiredArgs: () => ([
src,
dst,
mask
]),
expectOutput: () => {
channelIndices = ['x', 'y', 'z']
for (let row = 0; row < dst.rows; row++) {
for (let col = 0; col < dst.cols; col++) {
for (let channel = 0; channel < dst.channels; channel++) {
expect(dst.at(row, col)[channelIndices[channel]]).to.be.closeTo(expectedData[row][col][channel], 1e-5);
}
}
}
}
});
});

describe('accumulateProduct', () => {
const srcData1 = [
[[1, 2, 3], [4, 5, 6]],
[[7, 8, 9], [10, 11, 12]]
]
const srcData2 = [
[[2, 2, 2], [2, 2, 2]],
[[2, 2, 2], [2, 2, 2]]
]
const dstData = [
[[1, 1, 1], [1, 1, 1]],
[[1, 1, 1], [1, 1, 1]]
]
const maskData = [
[255, 0],
[0, 255]
]
const expectedData = [
[[3, 5, 7], [1, 1, 1]],
[[1, 1, 1], [21, 23, 25]]
]

const src1 = new cv.Mat(srcData1, cv.CV_8UC3)
const src2 = new cv.Mat(srcData2, cv.CV_8UC3)
let dst
const dstDepth8 = new cv.Mat(dstData, cv.CV_8UC3)
const mask = new cv.Mat(maskData, cv.CV_8UC1)

it('should throw if dst has not a depth of CV_32F or CV_64F', () => {
expect(() => cv.accumulateProduct(src1, src2, dstDepth8)).to.throw('Imgproc::AccumulateProduct - dst must has a depth of CV_32F or CV_64F');
});

generateAPITests({
getDut: () => cv,
methodName: 'accumulateProduct',
methodNameSpace: 'Imgproc',
beforeHook: () => dst = new cv.Mat(dstData, cv.CV_32FC3),
getRequiredArgs: () => ([
src1,
src2,
dst,
mask
]),
expectOutput: () => {
channelIndices = ['x', 'y', 'z']
for (let row = 0; row < dst.rows; row++) {
for (let col = 0; col < dst.cols; col++) {
for (let channel = 0; channel < dst.channels; channel++) {
expect(dst.at(row, col)[channelIndices[channel]]).to.be.closeTo(expectedData[row][col][channel], 1e-5);
}
}
}
}
});
});

describe('accumulateSquare', () => {
const srcData = [
[[1, 2, 3], [4, 5, 6]],
[[7, 8, 9], [10, 11, 12]]
]
const dstData = [
[[1, 1, 1], [1, 1, 1]],
[[1, 1, 1], [1, 1, 1]]
]
const maskData = [
[255, 0],
[0, 255]
]
const expectedData = [
[[2, 5, 10], [1, 1, 1]],
[[1, 1, 1], [101, 122, 145]]
]

const src = new cv.Mat(srcData, cv.CV_8UC3)
let dst
const dstDepth8 = new cv.Mat(dstData, cv.CV_8UC3)
const mask = new cv.Mat(maskData, cv.CV_8UC1)

it('should throw if dst has not a depth of CV_32F or CV_64F', () => {
expect(() => cv.accumulateSquare(src, dstDepth8)).to.throw('Imgproc::AccumulateSquare - dst must has a depth of CV_32F or CV_64F');
});

generateAPITests({
getDut: () => cv,
methodName: 'accumulateSquare',
methodNameSpace: 'Imgproc',
beforeHook: () => dst = new cv.Mat(dstData, cv.CV_32FC3),
getRequiredArgs: () => ([
src,
dst,
mask
]),
expectOutput: () => {
channelIndices = ['x', 'y', 'z']
for (let row = 0; row < dst.rows; row++) {
for (let col = 0; col < dst.cols; col++) {
for (let channel = 0; channel < dst.channels; channel++) {
expect(dst.at(row, col)[channelIndices[channel]]).to.be.closeTo(expectedData[row][col][channel], 1e-5);
}
}
}
}
});
});

describe('accumulateWeighted', () => {
const srcData = [
[[1, 2, 3], [4, 5, 6]],
[[7, 8, 9], [10, 11, 12]]
]
const dstData = [
[[1, 1, 1], [1, 1, 1]],
[[1, 1, 1], [1, 1, 1]]
]
const alpha = 0.7
const maskData = [
[255, 0],
[0, 255]
]
const expectedData = [
[[(1 - alpha) * 1 + alpha * 1, (1 - alpha) * 1 + alpha * 2, (1 - alpha) * 1 + alpha * 3], [1, 1, 1]],
[[1, 1, 1], [(1 - alpha) * 1 + alpha * 10, (1 - alpha) * 1 + alpha * 11, (1 - alpha) * 1 + alpha * 12]]
]

const src = new cv.Mat(srcData, cv.CV_8UC3)
let dst
const dstDepth8 = new cv.Mat(dstData, cv.CV_8UC3)
const mask = new cv.Mat(maskData, cv.CV_8UC1)

it('should throw if dst has not a depth of CV_32F or CV_64F', () => {
expect(() => cv.accumulateWeighted(src, dstDepth8, alpha)).to.throw('Imgproc::AccumulateWeighted - dst must has a depth of CV_32F or CV_64F');
});

generateAPITests({
getDut: () => cv,
methodName: 'accumulateWeighted',
methodNameSpace: 'Imgproc',
beforeHook: () => dst = new cv.Mat(dstData, cv.CV_32FC3),
getRequiredArgs: () => ([
src,
dst,
alpha,
mask
]),
expectOutput: () => {
channelIndices = ['x', 'y', 'z']
for (let row = 0; row < dst.rows; row++) {
for (let col = 0; col < dst.cols; col++) {
for (let channel = 0; channel < dst.channels; channel++) {
expect(dst.at(row, col)[channelIndices[channel]]).to.be.closeTo(expectedData[row][col][channel], 1e-5);
}
}
}
}
});
});
};

0 comments on commit fe29bb8

Please sign in to comment.