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, CV_32FC1, tempBGR[2]);
// merge the above into merged tempMatMChannI
Mat tempMatMChannI = Mat::zeros(3, 3, CV_32FC3);
tempMatSChanB.copyTo(tempMatMChannI.row(0));
tempMatSChanG.copyTo(tempMatMChannI.row(1));
tempMatSChanR.copyTo(tempMatMChannI.row(2));
tempMatMChannI.convertTo(tempMatMChannI, CV_8UC3);
// store in src
src.at<uchar>(i, j) = tempMatMChannI.at<uchar>(i, j);
}
}
imshow("conversion", src);
if (waitKey(30) >= 0) break;
}
}
I think that my problem lies around here:
// merge the above into merged tempMatMChannI
Mat tempMatMChannI = Mat::zeros(3, 3, CV_32FC3);
tempMatSChanB.copyTo(tempMatMChannI.row(0));
tempMatSChanG.copyTo(tempMatMChannI.row(1));
tempMatSChanR.copyTo(tempMatMChannI.row(2));
have i missed something? should i try other functions?