new GetPixel function that returns one of the following [B,G,R,A] or [B,G,R,A] or [G]

extended PixelCol and PixelRow so they will check for channels and return alpha too if possible

tests for GetPixel
This commit is contained in:
Leonid Babikov 2017-06-26 17:07:17 +03:00
parent 31ba216539
commit 7801cefdcd
3 changed files with 91 additions and 4 deletions

View File

@ -26,6 +26,7 @@ void Matrix::Init(Local<Object> target) {
Nan::SetPrototypeMethod(ctor, "pixelCol", PixelCol);
Nan::SetPrototypeMethod(ctor, "empty", Empty);
Nan::SetPrototypeMethod(ctor, "get", Get);
Nan::SetPrototypeMethod(ctor, "getPixel", GetPixel);
Nan::SetPrototypeMethod(ctor, "set", Set);
Nan::SetPrototypeMethod(ctor, "put", Put);
Nan::SetPrototypeMethod(ctor, "brightness", Brightness);
@ -274,6 +275,35 @@ NAN_METHOD(Matrix::Get) {
info.GetReturnValue().Set(Nan::New<Number>(val));
}
NAN_METHOD(Matrix::GetPixel) {
SETUP_FUNCTION(Matrix)
int y = info[0]->IntegerValue();
int x = info[1]->IntegerValue();
if (self->mat.channels() == 4) {
v8::Local < v8::Array > arr = Nan::New<Array>(4);
cv::Vec4b pixel = self->mat.at<cv::Vec4b>(y, x);
arr->Set(0, Nan::New<Number>((double) pixel.val[0]));
arr->Set(1, Nan::New<Number>((double) pixel.val[1]));
arr->Set(2, Nan::New<Number>((double) pixel.val[2]));
arr->Set(3, Nan::New<Number>((double) pixel.val[3]));
info.GetReturnValue().Set(arr);
} else if (self->mat.channels() == 3) {
v8::Local < v8::Array > arr = Nan::New<Array>(3);
cv::Vec3b pixel = self->mat.at<cv::Vec3b>(y, x);
arr->Set(0, Nan::New<Number>((double) pixel.val[0]));
arr->Set(1, Nan::New<Number>((double) pixel.val[1]));
arr->Set(2, Nan::New<Number>((double) pixel.val[2]));
info.GetReturnValue().Set(arr);
} else if(self->mat.channels() == 1) {
int pixel = (int)self->mat.at<unsigned char>(y, x);
info.GetReturnValue().Set(pixel);
} else {
Nan::ThrowTypeError("Only 4, 3 and 1 channel matrix are supported");
}
}
NAN_METHOD(Matrix::Set) {
SETUP_FUNCTION(Matrix)
@ -567,7 +597,17 @@ NAN_METHOD(Matrix::PixelRow) {
int y = info[0]->IntegerValue();
v8::Local < v8::Array > arr;
if (self->mat.channels() == 3) {
if (self->mat.channels() == 4) {
arr = Nan::New<Array>(width * 4);
for (int x = 0; x < width; x++) {
cv::Vec4b pixel = self->mat.at<cv::Vec4b>(y, x);
int offset = x * 4;
arr->Set(offset, Nan::New<Number>((double) pixel.val[0]));
arr->Set(offset + 1, Nan::New<Number>((double) pixel.val[1]));
arr->Set(offset + 2, Nan::New<Number>((double) pixel.val[2]));
arr->Set(offset + 3, Nan::New<Number>((double) pixel.val[3]));
}
} else if(self->mat.channels() == 3){
arr = Nan::New<Array>(width * 3);
for (int x = 0; x < width; x++) {
cv::Vec3b pixel = self->mat.at<cv::Vec3b>(y, x);
@ -576,12 +616,14 @@ NAN_METHOD(Matrix::PixelRow) {
arr->Set(offset + 1, Nan::New<Number>((double) pixel.val[1]));
arr->Set(offset + 2, Nan::New<Number>((double) pixel.val[2]));
}
} else {
} else if(self->mat.channels() == 1){
arr = Nan::New<Array>(width);
for (int x = 0; x < width; x++) {
int pixel = (int)self->mat.at<unsigned char>(y, x);
arr->Set(x, Nan::New<Number>(pixel));
}
} else {
Nan::ThrowTypeError("Only 4, 3 and 1 channel matrix are supported");
}
info.GetReturnValue().Set(arr);
@ -608,7 +650,17 @@ NAN_METHOD(Matrix::PixelCol) {
int x = info[0]->IntegerValue();
v8::Local < v8::Array > arr;
if (self->mat.channels() == 3) {
if (self->mat.channels() == 4) {
arr = Nan::New<Array>(height * 4);
for (int y = 0; y < height; y++) {
cv::Vec4b pixel = self->mat.at<cv::Vec4b>(y, x);
int offset = y * 4;
arr->Set(offset, Nan::New<Number>((double) pixel.val[0]));
arr->Set(offset + 1, Nan::New<Number>((double) pixel.val[1]));
arr->Set(offset + 2, Nan::New<Number>((double) pixel.val[2]));
arr->Set(offset + 3, Nan::New<Number>((double) pixel.val[3]));
}
} else if (self->mat.channels() == 3) {
arr = Nan::New<Array>(height * 3);
for (int y = 0; y < height; y++) {
cv::Vec3b pixel = self->mat.at<cv::Vec3b>(y, x);
@ -617,13 +669,16 @@ NAN_METHOD(Matrix::PixelCol) {
arr->Set(offset + 1, Nan::New<Number>((double) pixel.val[1]));
arr->Set(offset + 2, Nan::New<Number>((double) pixel.val[2]));
}
} else {
} else if(self->mat.channels() == 1) {
arr = Nan::New<Array>(height);
for (int y = 0; y < height; y++) {
int pixel = (int)self->mat.at<unsigned char>(y, x);
arr->Set(y, Nan::New<Number>(pixel));
}
} else {
Nan::ThrowTypeError("Only 4, 3 and 1 channel matrix are supported");
}
info.GetReturnValue().Set(arr);
}

View File

@ -20,6 +20,7 @@ public:
JSFUNC(Eye) // factory
JSFUNC(Get) // at
JSFUNC(GetPixel)
JSFUNC(Set)
JSFUNC(Put)

View File

@ -449,5 +449,36 @@ test('setColor works will alpha channels', function(assert) {
});
});
test('getPixel',function(assert){
cv.readImage('./examples/files/alpha-test.png', function(err, imgMat) {
if (!err) {
assert.equal(imgMat.channels(),4);
assert.deepEqual(imgMat.getPixel(10,10),[0,187,255,255]);
assert.deepEqual(imgMat.getPixel(30,80),[241,161,0,128]);
assert.deepEqual(imgMat.getPixel(80,30),[0,187,124,200]);
assert.deepEqual(imgMat.getPixel(80,80),[20,83,246,70]);
var channels = imgMat.split();
imgMat.merge([channels[0],channels[1],channels[2]]);
assert.equal(imgMat.channels(),3);
assert.deepEqual(imgMat.getPixel(10,10),[0,187,255]);
assert.deepEqual(imgMat.getPixel(30,80),[241,161,0]);
assert.deepEqual(imgMat.getPixel(80,30),[0,187,124]);
assert.deepEqual(imgMat.getPixel(80,80),[20,83,246]);
imgMat.merge([channels[3]]);
assert.equal(imgMat.channels(),1);
assert.deepEqual(imgMat.getPixel(0,0),255);
assert.deepEqual(imgMat.getPixel(30,80),128);
assert.deepEqual(imgMat.getPixel(80,30),200);
assert.deepEqual(imgMat.getPixel(80,80),70);
} else {
throw err;
}
assert.end();
});
});
// Test the examples folder.
require('./examples')()