From 2bce0b7cd273c7c21fc1d260d4329925878db93b Mon Sep 17 00:00:00 2001 From: Pierre Colle Date: Wed, 9 Nov 2016 09:16:04 +0100 Subject: [PATCH] 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)