Assertion fail when merging channels in OpenCV
I am working on a code that receives a video feed and edits it so that the video displayed has been altered in a way that the user sees what a colorblind person sees, the code is done but i am having issues merging the channels into a final frame. Here is the code i am using:
/*
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/utility.hpp"
#include <opencv2\core\core.hpp>
#include "iostream"
*/
using namespace cv; using namespace std;
int main(int argc, const char** argv) { VideoCapture cap(0); if (!cap.isOpened()) return -1; cap.set(CV_CAP_PROP_FRAME_HEIGHT, 400); cap.set(CV_CAP_PROP_FRAME_WIDTH, 400);
for (;;){
Mat frame;
cap >> frame;
Mat src = frame.clone();
vector<Mat> spl;
split(src, spl);
// Create an zero pixel image for filling purposes - will become clear later
// Also create container images for B G R channels as colour images
Mat empty_image = Mat::zeros(src.rows, src.cols, CV_8UC1);
Mat for_the_sake_of_safety = Mat::zeros(src.rows, src.cols, CV_32FC3);
Mat result_blue(src.rows, src.cols, CV_8UC3); // notice the 3 channels here!
Mat result_green(src.rows, src.cols, CV_8UC3); // notice the 3 channels here!
Mat result_red(src.rows, src.cols, CV_8UC3); // notice the 3 channels here!
Mat fresh = Mat::zeros(src.rows, src.cols, CV_8UC3);
// Create blue channel
Mat in1[] = { spl[0], empty_image, empty_image };
int from_to1[] = { 0, 0, 1, 1, 2, 2 };
mixChannels(in1, 3, &result_blue, 1, from_to1, 3);
// Create green channel
Mat in2[] = { empty_image, spl[1], empty_image };
int from_to2[] = { 0, 0, 1, 1, 2, 2 };
mixChannels(in2, 3, &result_green, 1, from_to2, 3);
// Create red channel
Mat in3[] = { empty_image, empty_image, spl[2] };
int from_to3[] = { 0, 0, 1, 1, 2, 2 };
mixChannels(in3, 3, &result_red, 1, from_to3, 3);
result_blue.convertTo(result_blue, CV_32FC3);
result_green.convertTo(result_green, CV_32FC3);
result_red.convertTo(result_red, CV_32FC3);
float tempBGR[3];
float L, M, S, LShift, MShift, SShift;
for (int i = 0; i < src.rows; i++){
for (int j = 0; j < src.cols * 3; j++){
// here is wher i define a new sub matrix
tempBGR[0] = result_blue.at<float>(i, j) / 255; // for scale
tempBGR[1] = result_green.at<float>(i, j) / 255;
tempBGR[2] = result_red.at<float>(i, j) / 255;
//could we alternatively make a separate float matrix to store things and then convert to Mat format
L = 17.8824 * tempBGR[2] + 43.5161 * tempBGR[1] + 4.1193 * tempBGR[0];
M = 3.45570 * tempBGR[2] + 27.1554 * tempBGR[1] + 3.8671 * tempBGR[0];
S = 0.02996 * tempBGR[2] + 0.18431 * tempBGR[1] + 1.4670 * tempBGR[0];
// LMS to L'M'S' {Tritanopia}
LShift = 1 * L + 0 * M + 0 * S;
MShift = 0 * L + 1 * M + 0 * S;
SShift = -0.395913 * L + 0.801109 * M + 0 * S;
// l'M'S' to BGR
tempBGR[2] = 0.080944942 * LShift - 0.130505254 * MShift + 0.116728267 * SShift;
tempBGR[1] = -0.010248719 * LShift + 0.05401967 * MShift - 0.11362094 * SShift;
tempBGR[0] = -0.000365487 * LShift - 0.004121628 * MShift + 0.693554394 * SShift;
Mat tempMatSChanB = Mat(1, 3, CV_32FC1, tempBGR[0]);
Mat tempMatSChanG = Mat(1, 3, CV_32FC1, tempBGR[1]);
Mat tempMatSChanR = Mat(1, 3 ...
Well, the Mats you are trying to copy from are one channel, and you are trying to copy into a 3 channel Mat.
Change the type to CV_32FC1 and use the copys, or change the size of tempMatMChannI to (1,3) and use cv::merge(tempBGR, 3, tempMatMChannI). Which one depends on the the precise details. I think you want the second, using merge.
I should also point out that the store in src bit only copies one channel. Replace the uchar with
to get all three channels.
After adjusting the channels the error still lies on merge, the problem is: the argument list does not match (float[3], int, cv::Mat )