From 2bce0b7cd273c7c21fc1d260d4329925878db93b Mon Sep 17 00:00:00 2001 From: Pierre Colle Date: Wed, 9 Nov 2016 09:16:04 +0100 Subject: [PATCH 1/4] image signature, slow but working --- examples/mat-dct.js | 116 ++++++++++++++++++++++++++++++++++++++++---- src/Matrix.cc | 24 +++++++-- src/Matrix.h | 3 +- 3 files changed, 130 insertions(+), 13 deletions(-) diff --git a/examples/mat-dct.js b/examples/mat-dct.js index b3fa89f..ec9d193 100644 --- a/examples/mat-dct.js +++ b/examples/mat-dct.js @@ -1,22 +1,120 @@ var cv = require('../lib/opencv'); +var createGaussianKernel = function(sigma){ + var cst = 1; + var denom = (2*sigma*sigma); + var factor = 100; + return { + get : function(i,j){ + //console.log(cst, denom, ((i/10)*(i/10)+(j/10)*(j/10)), denom, Math.exp((i*i+j*j)/denom)) + return cst*Math.exp(-1*(i*i+j*j)/denom); + } + } +}; + +var convolve = function(m1, m2){ + var nCols = m1.width(); + var nRows = m1.height(); + + var max = 0; + + var res = new cv.Matrix(nRows, nCols, cv.Constants.CV_32FC1); + + for(var i = 0; i < nCols; i++){ + for(var j = 0; j < nRows; j++){ + sum = 0; + + for(var i2 = i-nCols+1; i2 <= i; i2++){ + for(var j2 = j-nRows+1; j2 <= j; j2++){ + sum += m1.get(i-i2,j-j2)*m2.get(i2,j2) + if(isNaN(sum)){ + console.log(m1.get(i-i2,j-j2),m2.get(i2,j2), i-i2,i2,j-j2,j2) + throw("sum is NaN") + } + } + } + //console.log(sum) + + if(sum > max){ + max = sum + } + + res.set(i,j, sum); + } + } + //console.log(max); + + for(var i = 0; i < nCols; i++){ + for(var j = 0; j < nRows; j++){ + res.set(i,j, res.get(i,j)/max); + } + } + return res; + +}; + +var getSalient = function(channel){ + var floatInputMatrix = new cv.Matrix(); + channel.convertTo(floatInputMatrix, cv.Constants.CV_32F); + var floatAfterDct = floatInputMatrix.dct(); + + var nCols = channel.width(); + var nRows = channel.height(); + + var signs = new cv.Matrix(nRows, nCols, cv.Constants.CV_32FC1); + var arr = []; + for(var i = 0; i < nCols; i++){ + var row = []; + for(var j = 0; j < nRows; j++){ + if(floatAfterDct.get(i,j) < 0){ + signs.set(i, j, -1); + } else if(floatAfterDct.get(i,j) == 0){ + signs.set(i, j, 0); + } else { + signs.set(i, j, 1); + } + } + arr.push(row) + } + // for inverse dct, set argument to "true" + var afterDoubleDct = signs.idct(); + //console.log(afterDoubleDct.getData()) + var squaredFloat = new cv.Matrix(nRows, nCols, cv.Constants.CV_32FC1); + + for(var i = 0; i < nCols; i++){ + for(var j = 0; j < nRows; j++){ + var v = afterDoubleDct.get(i,j) + squaredFloat.set(i,j, v * v) + } + } + + var sigma = 0.3; + + var res = convolve(squaredFloat, createGaussianKernel(sigma)) + var outChannel = new cv.Matrix(nRows, nCols, cv.Constants.CV_8U); + + res.convertTo(outChannel, cv.Constants.CV_8U, 255); + + return outChannel; +}; + cv.readImage("./files/mona.png", function(err, orig) { if (err) throw err; - var chan1 = orig.split()[0]; + orig.resize(64, 64); - var floatInputMatrix = new cv.Matrix(); - chan1.convertTo(floatInputMatrix, cv.Constants.CV_32F) + var channels = orig.split(); + var outChannels = []; - var foatAfterDct = floatInputMatrix.dct(); + for(var chanIdx = 0; chanIdx < channels.length; chanIdx++){ + outChannels.push(getSalient(channels[chanIdx])); + } - // for inverse dct, set argument to "true" - var afterDoubleDct = foatAfterDct.dct(true); + var outImg = new cv.Matrix() - var intOutImage = new cv.Matrix(); + outImg.merge(outChannels) - afterDoubleDct.convertTo(intOutImage, cv.Constants.CV_8U); - intOutImage.save("./tmp/dct.png"); + outImg.save("./tmp/dct.png"); console.log('Image saved to ./tmp/dct.png'); }); diff --git a/src/Matrix.cc b/src/Matrix.cc index 72d54bd..ddcd592 100755 --- a/src/Matrix.cc +++ b/src/Matrix.cc @@ -66,6 +66,7 @@ void Matrix::Init(Local target) { Nan::SetPrototypeMethod(ctor, "ptr", Ptr); Nan::SetPrototypeMethod(ctor, "absDiff", AbsDiff); Nan::SetPrototypeMethod(ctor, "dct", Dct); + Nan::SetPrototypeMethod(ctor, "idct", Idct); Nan::SetPrototypeMethod(ctor, "addWeighted", AddWeighted); Nan::SetPrototypeMethod(ctor, "bitwiseXor", BitwiseXor); Nan::SetPrototypeMethod(ctor, "bitwiseNot", BitwiseNot); @@ -290,6 +291,9 @@ NAN_METHOD(Matrix::Set) { self->mat.at(i, j)[2] = (uchar) (vint) & 0xff; // printf("!!!i %x, %x, %x", (vint >> 16) & 0xff, (vint >> 8) & 0xff, (vint) & 0xff); break; + case CV_32FC1: + self->mat.at(i, j) = val; + break; default: self->mat.at(i, j) = val; } @@ -1288,13 +1292,27 @@ NAN_METHOD(Matrix::Dct) { int cols = self->mat.cols; int rows = self->mat.rows; - bool inverse = info[1]->ToBoolean()->Value(); + Local out = Nan::New(Matrix::constructor)->GetFunction()->NewInstance(); + Matrix *m_out = Nan::ObjectWrap::Unwrap(out); + m_out->mat.create(cols, rows, CV_32F); + + cv::dct(self->mat, m_out->mat); + + info.GetReturnValue().Set(out); +} + +NAN_METHOD(Matrix::Idct) { + Nan::HandleScope scope; + + Matrix *self = Nan::ObjectWrap::Unwrap(info.This()); + int cols = self->mat.cols; + int rows = self->mat.rows; Local out = Nan::New(Matrix::constructor)->GetFunction()->NewInstance(); Matrix *m_out = Nan::ObjectWrap::Unwrap(out); - m_out->mat.create(rows, cols, CV_32F); + m_out->mat.create(cols, rows, CV_32F); - cv::dct(self->mat, m_out->mat, inverse ? 1 : 0); + cv::idct(self->mat, m_out->mat); info.GetReturnValue().Set(out); } diff --git a/src/Matrix.h b/src/Matrix.h index ee337e6..cf9e65d 100755 --- a/src/Matrix.h +++ b/src/Matrix.h @@ -68,7 +68,8 @@ public: JSFUNC(ROI) JSFUNC(Ptr) JSFUNC(AbsDiff) - JSFUNC(Dct) + JSFUNC(Dct) + JSFUNC(Idct) JSFUNC(AddWeighted) JSFUNC(BitwiseXor) JSFUNC(BitwiseNot) From fe2b18e0a75b7d2a4a6f2409cd7e75d78455ffa3 Mon Sep 17 00:00:00 2001 From: Pierre Colle Date: Wed, 9 Nov 2016 10:19:26 +0100 Subject: [PATCH 2/4] add sigma param to gaussianBlur --- src/Matrix.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Matrix.cc b/src/Matrix.cc index ddcd592..7fda60f 100755 --- a/src/Matrix.cc +++ b/src/Matrix.cc @@ -1100,6 +1100,7 @@ NAN_METHOD(Matrix::GaussianBlur) { cv::Mat blurred; Matrix *self = Nan::ObjectWrap::Unwrap(info.This()); + double sigma = 0; if (info.Length() < 1) { ksize = cv::Size(5, 5); @@ -1116,9 +1117,12 @@ NAN_METHOD(Matrix::GaussianBlur) { Nan::ThrowTypeError("'ksize' argument must be a 2 double array"); } ksize = cv::Size(x->NumberValue(), y->NumberValue()); + if (info[1]->IsNumber()) { + sigma = info[1]->ToNumber()->Value(); + } } - cv::GaussianBlur(self->mat, blurred, ksize, 0); + cv::GaussianBlur(self->mat, blurred, ksize, sigma); blurred.copyTo(self->mat); info.GetReturnValue().Set(Nan::Null()); From 430976cb1a31366d0bf0342dd54fd84b3a14b7c6 Mon Sep 17 00:00:00 2001 From: Pierre Colle Date: Wed, 9 Nov 2016 10:20:33 +0100 Subject: [PATCH 3/4] wrap add function --- src/Matrix.cc | 24 ++++++++++++++++++++++++ src/Matrix.h | 3 ++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/Matrix.cc b/src/Matrix.cc index 7fda60f..46be360 100755 --- a/src/Matrix.cc +++ b/src/Matrix.cc @@ -68,6 +68,7 @@ void Matrix::Init(Local target) { Nan::SetPrototypeMethod(ctor, "dct", Dct); Nan::SetPrototypeMethod(ctor, "idct", Idct); Nan::SetPrototypeMethod(ctor, "addWeighted", AddWeighted); + Nan::SetPrototypeMethod(ctor, "add", Add); Nan::SetPrototypeMethod(ctor, "bitwiseXor", BitwiseXor); Nan::SetPrototypeMethod(ctor, "bitwiseNot", BitwiseNot); Nan::SetPrototypeMethod(ctor, "bitwiseAnd", BitwiseAnd); @@ -1342,6 +1343,29 @@ NAN_METHOD(Matrix::AddWeighted) { info.GetReturnValue().Set(Nan::Null()); } +NAN_METHOD(Matrix::Add) { + Nan::HandleScope scope; + + Matrix *self = Nan::ObjectWrap::Unwrap(info.This()); + int cols = self->mat.cols; + int rows = self->mat.rows; + + Matrix *src1 = Nan::ObjectWrap::Unwrap(info[0]->ToObject()); + + Local out = Nan::New(Matrix::constructor)->GetFunction()->NewInstance(); + Matrix *m_out = Nan::ObjectWrap::Unwrap(out); + m_out->mat.create(cols, rows, self->mat.type()); + + try { + cv::add(self->mat, src1->mat, m_out->mat); + } catch(cv::Exception& e ) { + const char* err_msg = e.what(); + Nan::ThrowError(err_msg); + } + + info.GetReturnValue().Set(out); +} + NAN_METHOD(Matrix::BitwiseXor) { Nan::HandleScope scope; diff --git a/src/Matrix.h b/src/Matrix.h index cf9e65d..7aaf473 100755 --- a/src/Matrix.h +++ b/src/Matrix.h @@ -69,8 +69,9 @@ public: JSFUNC(Ptr) JSFUNC(AbsDiff) JSFUNC(Dct) - JSFUNC(Idct) + JSFUNC(Idct) JSFUNC(AddWeighted) + JSFUNC(Add) JSFUNC(BitwiseXor) JSFUNC(BitwiseNot) JSFUNC(BitwiseAnd) From aeb2618a345dd7a180faa505d74a1b735da07202 Mon Sep 17 00:00:00 2001 From: Pierre Colle Date: Sat, 12 Nov 2016 17:34:06 +0100 Subject: [PATCH 4/4] revert dct example --- examples/mat-dct.js | 116 ++++---------------------------------------- 1 file changed, 9 insertions(+), 107 deletions(-) diff --git a/examples/mat-dct.js b/examples/mat-dct.js index ec9d193..b3fa89f 100644 --- a/examples/mat-dct.js +++ b/examples/mat-dct.js @@ -1,120 +1,22 @@ var cv = require('../lib/opencv'); -var createGaussianKernel = function(sigma){ - var cst = 1; - var denom = (2*sigma*sigma); - var factor = 100; - return { - get : function(i,j){ - //console.log(cst, denom, ((i/10)*(i/10)+(j/10)*(j/10)), denom, Math.exp((i*i+j*j)/denom)) - return cst*Math.exp(-1*(i*i+j*j)/denom); - } - } -}; - -var convolve = function(m1, m2){ - var nCols = m1.width(); - var nRows = m1.height(); - - var max = 0; - - var res = new cv.Matrix(nRows, nCols, cv.Constants.CV_32FC1); - - for(var i = 0; i < nCols; i++){ - for(var j = 0; j < nRows; j++){ - sum = 0; - - for(var i2 = i-nCols+1; i2 <= i; i2++){ - for(var j2 = j-nRows+1; j2 <= j; j2++){ - sum += m1.get(i-i2,j-j2)*m2.get(i2,j2) - if(isNaN(sum)){ - console.log(m1.get(i-i2,j-j2),m2.get(i2,j2), i-i2,i2,j-j2,j2) - throw("sum is NaN") - } - } - } - //console.log(sum) - - if(sum > max){ - max = sum - } - - res.set(i,j, sum); - } - } - //console.log(max); - - for(var i = 0; i < nCols; i++){ - for(var j = 0; j < nRows; j++){ - res.set(i,j, res.get(i,j)/max); - } - } - return res; - -}; - -var getSalient = function(channel){ - var floatInputMatrix = new cv.Matrix(); - channel.convertTo(floatInputMatrix, cv.Constants.CV_32F); - var floatAfterDct = floatInputMatrix.dct(); - - var nCols = channel.width(); - var nRows = channel.height(); - - var signs = new cv.Matrix(nRows, nCols, cv.Constants.CV_32FC1); - var arr = []; - for(var i = 0; i < nCols; i++){ - var row = []; - for(var j = 0; j < nRows; j++){ - if(floatAfterDct.get(i,j) < 0){ - signs.set(i, j, -1); - } else if(floatAfterDct.get(i,j) == 0){ - signs.set(i, j, 0); - } else { - signs.set(i, j, 1); - } - } - arr.push(row) - } - // for inverse dct, set argument to "true" - var afterDoubleDct = signs.idct(); - //console.log(afterDoubleDct.getData()) - var squaredFloat = new cv.Matrix(nRows, nCols, cv.Constants.CV_32FC1); - - for(var i = 0; i < nCols; i++){ - for(var j = 0; j < nRows; j++){ - var v = afterDoubleDct.get(i,j) - squaredFloat.set(i,j, v * v) - } - } - - var sigma = 0.3; - - var res = convolve(squaredFloat, createGaussianKernel(sigma)) - var outChannel = new cv.Matrix(nRows, nCols, cv.Constants.CV_8U); - - res.convertTo(outChannel, cv.Constants.CV_8U, 255); - - return outChannel; -}; - cv.readImage("./files/mona.png", function(err, orig) { if (err) throw err; - orig.resize(64, 64); + var chan1 = orig.split()[0]; - var channels = orig.split(); - var outChannels = []; + var floatInputMatrix = new cv.Matrix(); + chan1.convertTo(floatInputMatrix, cv.Constants.CV_32F) - for(var chanIdx = 0; chanIdx < channels.length; chanIdx++){ - outChannels.push(getSalient(channels[chanIdx])); - } + var foatAfterDct = floatInputMatrix.dct(); - var outImg = new cv.Matrix() + // for inverse dct, set argument to "true" + var afterDoubleDct = foatAfterDct.dct(true); - outImg.merge(outChannels) + var intOutImage = new cv.Matrix(); - outImg.save("./tmp/dct.png"); + afterDoubleDct.convertTo(intOutImage, cv.Constants.CV_8U); + intOutImage.save("./tmp/dct.png"); console.log('Image saved to ./tmp/dct.png'); });