White Balance the Camera Capture on OpenCV (C++)

How to fix this white balancing issue? I have seen some examples on python but couldn’t implement them to c++. And as far as I saw, there is not a built in function other than this WhiteBalance on openCV.

Here are my progress and the current results:

VideoCapture cap;

VideoStreamer::VideoStreamer()
{
    connect(&tUpdate,&QTimer::timeout,this,&VideoStreamer::streamVideo);    
}

VideoStreamer::~VideoStreamer()
{
    cap.release();
    tUpdate.stop();
}
 
void VideoStreamer::streamVideo()
{
    //Capture frame by frame
    cap>>frame;
    cvtColor(frame, frame, cv::COLOR_BayerGR2BGR);

    //WhiteBalance
    Ptr<xphoto::WhiteBalancer> wb;
    wb = xphoto::createLearningBasedWB();
    wb ->balanceWhite(frame, frame);

    QImage imgOriginal = QImage(frame.data,frame.cols,frame.rows,QImage::Format_BGR888).rgbSwapped();
}

void VideoStreamer::openVideoCamera()
{
   int deviceID = 1;
   int apiID = cv::CAP_ANY;
   cap.open(deviceID, apiID);

   double fps = cap.get(cv::CAP_PROP_FPS);
   tUpdate.start(0);
}

After White Balance:

do you know why you used COLOR_BayerGR2BGR?

Try to set the white balance in the camera with cap.set():

CAP_PROP_AUTO_WB - enable/ disable auto white-balance
CAP_PROP_WB_TEMPERATURE - white-balance color temperature

It’s better to do it in camera because it can work with raw data, which has much better color resolution than the captured and compressed captured images.

Here you have a list of typical white balance values:

related:

Yes because i was getting some silly-broken captures before that. It was working fine on the camera app but was broken on the opencv. So i looked and saw that the app was using GRBG, that’s why I converted the bayer image.

I changed the codes like this:

void VideoStreamer::openVideoCamera()
{
   cap.open(0);
   cap.set(CAP_PROP_AUTO_WB, 0);
   cap.set(CAP_PROP_WB_TEMPERATURE,10);
   double fps = cap.get(cv::CAP_PROP_FPS);
   tUpdate.start(1000/fps);
}

But the capture never changes, whatever i write as a parameter to temperature, it stays the same. Am I missing something?

If it is not something that I can do on Opencv, can you help me with changing the camera API?

My camera model: DFM 27UR0135-ML - USB 3.0 color board camera

I am working on Linux - Ubuntu. I thought I could change the parameters through v4l2. I think I should open the camera by specifying V4L2 for the changes to be set on the opencv. But it crashes when I write v4l2 with the following error.

void VideoStreamer::openVideoCamera()
{
   cap.open(0, CAP_V4L2); //I also tried with just writing CAP_V4L2 but it didnt work.
}

OpenCV(4.5.3-dev) opencv-master/modules/imgproc/src/demosaicing.cpp:1721: error: (-215:Assertion failed) scn == 1 && (dcn == 3 || dcn == 4) in function 'demosaicing’

related: