mirror of
https://github.com/peterbraden/node-opencv.git
synced 2025-12-08 19:45:55 +00:00
Histogram now takes multiple dimensions
This commit is contained in:
parent
2839bce325
commit
1bb61fc38a
@ -9,19 +9,59 @@ cv.readImage('./files/car1.jpg', function(err, im) {
|
||||
|
||||
var bgrPlanes = im.split();
|
||||
|
||||
var size = 4,
|
||||
var size = 256,
|
||||
range = [0, 256],
|
||||
uniform = true,
|
||||
accumulate = true,
|
||||
histFile = 'files/chart.png';
|
||||
histFile = 'files/chart2.png';
|
||||
|
||||
|
||||
/// Compute the histograms:
|
||||
var bHist = cv.histogram.calcHist( bgrPlanes[0], size, range, 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 hist64 = cv.histogram.calcHist( im, [0, 1, 2], [4, 4, 4], [[0, 256], [0, 256], [0, 256]], uniform, accumulate );
|
||||
|
||||
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)
|
||||
});
|
||||
*/
|
||||
});
|
||||
|
||||
107
src/Histogram.cc
107
src/Histogram.cc
@ -20,43 +20,102 @@ NAN_METHOD(Histogram::CalcHist) {
|
||||
Matrix* m0 = Nan::ObjectWrap::Unwrap<Matrix>(info[0]->ToObject());
|
||||
cv::Mat inputImage = m0->mat;
|
||||
|
||||
// Arg 1 is histogram sizes in first dimension
|
||||
/// Establish the number of bins
|
||||
int histSize = info[1]->IntegerValue();
|
||||
|
||||
// Arg 2 is array of the histogram bin boundaries in each dimension
|
||||
|
||||
Local<Array> nodeRange = Local<Array>::Cast(info[2]->ToObject());
|
||||
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();
|
||||
//int dims = 3;
|
||||
// Arg 1 is the channel
|
||||
Local<Array> nodeChannels = Local<Array>::Cast(info[1]->ToObject());
|
||||
const unsigned int dims = nodeChannels->Length();
|
||||
int channels[dims];
|
||||
for (unsigned int i = 0; i < dims; i++) {
|
||||
channels[i] = nodeChannels->Get(i)->IntegerValue();
|
||||
}
|
||||
const float* histRange = { range };
|
||||
|
||||
// Arg 3 is uniform flag
|
||||
bool uniform = info[3]->BooleanValue();
|
||||
//int channels[] = {0, 1, 2};
|
||||
|
||||
// Arg 4 is accumulate flag
|
||||
bool accumulate = info[4]->BooleanValue();
|
||||
// Arg 2 is histogram sizes in each dimension
|
||||
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
|
||||
cv::Mat outputHist;
|
||||
|
||||
// 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
|
||||
//Local<Object> outMatrixWrap = Nan::NewInstance(Nan::GetFunction(Nan::New(Matrix::constructor)).ToLocalChecked()).ToLocalChecked();
|
||||
//Matrix *outMatrix = Nan::ObjectWrap::Unwrap<Matrix>(outMatrixWrap);
|
||||
//outMatrix->mat = outputHist;
|
||||
/*Local<Object> outMatrixWrap = Nan::NewInstance(Nan::GetFunction(Nan::New(Matrix::constructor)).ToLocalChecked()).ToLocalChecked();
|
||||
Matrix *outMatrix = Nan::ObjectWrap::Unwrap<Matrix>(outMatrixWrap);
|
||||
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]);
|
||||
|
||||
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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user