Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

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, 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?