I’m very new to OpenCV and currently using OpenCVJS in one of my projects.
So far, I am able to convert the python and c++ references I see online to JS. However, I am stuck with trying to apply white balance to an image.
For the C++ there is a white balancer method here but unfortunately there is none in JS.
I have used this reference in trying to replicate this to JS but I have no progress: Reference 1
Here is my code:
let src = cv.imread(canvasId);
let imageRGB = new cv.MatVector();
let dst = new cv.Mat();
cv.split(src, imageRGB);
let b = imageRGB.get(0);
let g = imageRGB.get(1);
let r = imageRGB.get(2);
const b_avg = cv.mean(b)[0];
const g_avg = cv.mean(g)[0];
const r_avg = cv.mean(r)[0];
let k = (r_avg + g_avg + b_avg) / 3;
let kr = k / r_avg;
let kg = k / g_avg;
let kb = k / b_avg;
// for this part, i am not sure of. I do not know how to manipulate the channel data based
// on the calculations made above
let row = 3, col = 4;
r.data[row * r.cols * r.channels() + col * r.channels() + kr];
g.data[row * g.cols * b.channels() + col * b.channels() + kg];
b.data[row * b.cols * b.channels() + col * b.channels() + kb];
// I am also not sure how to merge back the indivudual channels back into imageRGB
// since calling cv.merge([b,g,r]) will result to an error based on the JS documentation. It
// needs 2 parameters to work.
imageRGB.push_back(b);
imageRGB.push_back(g);
imageRGB.push_back(r);
cv.merge(imageRGB,src);
// throws an error since this needs a cv.Mat type, but I do not know how to utilize dst in this
cv.imshow('outputCanvas', imageRGB);
src.delete();
imageRGB.delete();
dst.delete();
Thank you for your patience. I would appreciate any help from this. JS related concerns are not as abundant as Python and C++
you really should use the “vectorized” version of that python code (see the edit to the answer there), not write loops at all !
let src = cv.imread('canvasInput');
let lab = new cv.Mat();
cv.cvtColor(src, lab, cv.COLOR_RGB2Lab);
let chan = new cv.MatVector();
cv.split(lab, chan);
let L = chan.get(0);
let A = chan.get(1);
let B = chan.get(2);
let ma = cv.mean(A)[0];
let mb = cv.mean(B)[0];
A = A - ((ma - 128.0) * (L / 255.0) * 1.1);
B = B - ((mb - 128.0) * (L / 255.0) * 1.1);
cv.merge(chan, lab);
let dst = new cv.Mat();
cv.cvtColor(lab, dst, cv.COLOR_Lab2RGB);
cv.imshow('canvasOutput', dst);
Thank you very much for your response! I have made some progress with this!
Unfortunately, I am stuck at this part of the code:
A = A - ((ma - 128.0) * (L / 255.0) * 1.1);
B = B - ((mb - 128.0) * (L / 255.0) * 1.1);
I am not sure how to manipulate the values of the A and B Mats in Javascript since I get these errors.
“Type ‘number’ is not assignable to type ‘Mat’”
“The left-hand side of an arithmetic operation must be of type ‘any’, ‘number’, ‘bigint’ or an enum type”
I’ve checked the official docs on how to manipulate pixel values here but I’m finding it hard to understand as a beginner
Thank you again for your patience!
*Edit: It seems that regular operations are not applicable to OpenCV JS. I have found the following operations but they require 2 Mats for src1 and src2