Histogram now takes multiple dimensions

This commit is contained in:
Pierre Colle 2017-08-23 19:14:32 +02:00
parent 2839bce325
commit 1bb61fc38a
2 changed files with 131 additions and 32 deletions

View File

@ -9,19 +9,59 @@ cv.readImage('./files/car1.jpg', function(err, im) {
var bgrPlanes = im.split(); var bgrPlanes = im.split();
var size = 4, var size = 256,
range = [0, 256], range = [0, 256],
uniform = true, uniform = true,
accumulate = true, accumulate = true,
histFile = 'files/chart.png'; histFile = 'files/chart2.png';
/// Compute the histograms: /// Compute the histograms:
var bHist = cv.histogram.calcHist( bgrPlanes[0], size, range, uniform, accumulate ); var hist64 = cv.histogram.calcHist( im, [0, 1, 2], [4, 4, 4], [[0, 256], [0, 256], [0, 256]], uniform, accumulate );
var gHist = cv.histogram.calcHist( bgrPlanes[1], size, range, uniform, accumulate );
var rHist = cv.histogram.calcHist( bgrPlanes[2], size, range, uniform, accumulate );
console.log("Histograms are \n Blue : ", bHist, "\n Green : ", gHist, "\n Red : ", rHist);
var bHist = cv.histogram.calcHist( im, [0], [size], [range], uniform, accumulate );
var gHist = cv.histogram.calcHist( im, [1], [size], [range], uniform, accumulate );
var rHist = cv.histogram.calcHist( im, [2], [size], [range], uniform, accumulate );
//////
// Uncommentand run `npm install chartjs-node` to draw the histogram !
///
/*
var ChartjsNode = require('chartjs-node');
var chartNode = new ChartjsNode(1200, 1200);
chartNode.drawChart({
type: 'bar',
data: {
labels: bHist.map(function(a,i){return i.toString()}),
datasets : [{
data : bHist,
backgroundColor : "#4183c4",
borderColor : "#0c4b8a",
label : 'Blue'
},{
data : gHist,
backgroundColor : "#83c441",
borderColor : "#0c4b8a",
label : 'Green'
},{
data : rHist,
backgroundColor : "#c44183",
borderColor : "#0c4b8a",
label : 'Red'
}]
},
options: {
title: {
display: true,
text: 'RGB Histograms'
}
}
}).then(function(){
return chartNode.writeImageToFile('image/png', histFile);
}).then(function(){
console.log("result has been written in "+histFile)
}).catch(function(e){
console.log("error",e)
});
*/
}); });

View File

@ -20,43 +20,102 @@ NAN_METHOD(Histogram::CalcHist) {
Matrix* m0 = Nan::ObjectWrap::Unwrap<Matrix>(info[0]->ToObject()); Matrix* m0 = Nan::ObjectWrap::Unwrap<Matrix>(info[0]->ToObject());
cv::Mat inputImage = m0->mat; cv::Mat inputImage = m0->mat;
// Arg 1 is histogram sizes in first dimension //int dims = 3;
/// Establish the number of bins // Arg 1 is the channel
int histSize = info[1]->IntegerValue(); Local<Array> nodeChannels = Local<Array>::Cast(info[1]->ToObject());
const unsigned int dims = nodeChannels->Length();
// Arg 2 is array of the histogram bin boundaries in each dimension int channels[dims];
for (unsigned int i = 0; i < dims; i++) {
Local<Array> nodeRange = Local<Array>::Cast(info[2]->ToObject()); channels[i] = nodeChannels->Get(i)->IntegerValue();
unsigned int num_range = nodeRange->Length();
/// Set the ranges ( for B,G,R) )
float range[num_range];
for (unsigned int i = 0; i < num_range; i++) {
range[i] = nodeRange->Get(i)->NumberValue();
} }
const float* histRange = { range };
// Arg 3 is uniform flag //int channels[] = {0, 1, 2};
bool uniform = info[3]->BooleanValue();
// Arg 4 is accumulate flag // Arg 2 is histogram sizes in each dimension
bool accumulate = info[4]->BooleanValue(); Local<Array> nodeHistSizes = Local<Array>::Cast(info[2]->ToObject());
int histSize[dims];
for (unsigned int i = 0; i < dims; i++) {
histSize[i] = nodeHistSizes->Get(i)->IntegerValue();
}
// Arg 3 is array of the histogram bin boundaries in each dimension
Local<Array> nodeRanges = Local<Array>::Cast(info[3]->ToObject());
/// Set the ranges ( for B,G,R) )
float histRanges[dims][2];
for (unsigned int i = 0; i < dims; i++) {
Local<Array> nodeRange = Local<Array>::Cast(nodeRanges->Get(i)->ToObject());
float lower = nodeRange->Get(0)->NumberValue();
float higher = nodeRange->Get(1)->NumberValue();
histRanges[i][0] = lower;
histRanges[i][1] = higher;
}
float first_range[] = { histRanges[0][0], histRanges[0][1] };
float second_range[] = { 0, 0};
float third_range[] = { 0, 0};
if(dims >= 2){
second_range[0] = histRanges[1][0];
second_range[1] = histRanges[1][1];
}
if(dims >= 3){
third_range[0] = histRanges[2][0];
third_range[1] = histRanges[2][1];
}
const float* histRanges1[] = {first_range, second_range, third_range};
// Arg 4 is uniform flag
bool uniform = info[4]->BooleanValue();
// Arg 5 is accumulate flag
bool accumulate = info[5]->BooleanValue();
/*
float rranges[] = { 0, 256 };
float granges[] = { 0, 256 };
float branges[] = { 0, 256 };
const float* histRange[] = { rranges, granges, branges};
*/
// Make a mat to hold the result image // Make a mat to hold the result image
cv::Mat outputHist; cv::Mat outputHist;
// Perform calcHist // Perform calcHist
cv::calcHist(&inputImage, 1, 0, cv::Mat(), outputHist, 1, &histSize, &histRange, uniform, accumulate); cv::calcHist(&inputImage, 1, channels, cv::Mat(), outputHist, dims, histSize, histRanges1, uniform, accumulate);
// Wrap the output image // Wrap the output image
//Local<Object> outMatrixWrap = Nan::NewInstance(Nan::GetFunction(Nan::New(Matrix::constructor)).ToLocalChecked()).ToLocalChecked(); /*Local<Object> outMatrixWrap = Nan::NewInstance(Nan::GetFunction(Nan::New(Matrix::constructor)).ToLocalChecked()).ToLocalChecked();
//Matrix *outMatrix = Nan::ObjectWrap::Unwrap<Matrix>(outMatrixWrap); Matrix *outMatrix = Nan::ObjectWrap::Unwrap<Matrix>(outMatrixWrap);
//outMatrix->mat = outputHist; outMatrix->mat = outputHist;
v8::Local<v8::Array> arr = Nan::New<Array>(histSize); info.GetReturnValue().Set(outMatrixWrap);*/
for (unsigned int i=0; i < (unsigned int) histSize; i++) { v8::Local<v8::Array> arr = Nan::New<Array>(histSize[0]);
arr->Set(i, Nan::New<Number>(outputHist.at<float>(i)));
if(dims < 1 || dims > 3){
return Nan::ThrowTypeError("OPENCV nodejs binding error : only dimensions from 1 to 3 are allowed");
}
for (unsigned int i=0; i < (unsigned int) histSize[0]; i++) {
if(dims <= 1){
arr->Set(i, Nan::New<Number>(outputHist.at<float>(i)));
} else {
v8::Local<v8::Array> arr2 = Nan::New<Array>(dims);
for (unsigned int j=0; j < (unsigned int) histSize[1]; j++) {
if(dims <= 2){
arr2->Set(j, Nan::New<Number>(outputHist.at<float>(i,j)));
} else {
v8::Local<v8::Array> arr3 = Nan::New<Array>(dims);
for (unsigned int k=0; k < (unsigned int) histSize[1]; k++) {
arr3->Set(k, Nan::New<Number>(outputHist.at<float>(i,j,k)));
}
arr2->Set(j, arr3);
}
}
arr->Set(i, arr2);
}
} }
info.GetReturnValue().Set(arr); info.GetReturnValue().Set(arr);