Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Loading two Mats into split short arrays?

I am trying to replace an existing function with openCv for image handling. This is the function:

ImageBMP::ImageBMP(char * filename) {
    this->filename = filename;
    this->height = 0;
    this->width = 0;
    this->valid = 1;
    this->datapos = -1;
    this->file = nullptr;
}

    ImageBMP* fg = new ImageBMP("test2.bmp");
    ImageBMP* bg = new ImageBMP("back.bmp");

short* fgbgR = new short[size];
    short* fgbgG = new short[size];
    short* fgbgB = new short[size];


    pos = fg->datapos;
    int mx = 3 * fg->width;
    switch (mx % 4)
    {
    case 1:
        mx = mx + 3;
        break;
    case 2:
        mx = mx + 2;
        break;
    case 3:
        mx = mx + 1;
        break;
    }

    std::cout << pos << std::endl;


    // Fill matrix for Foreground and Background
    int i = 0;
    int j = 0;
    for (i = 0; i < fg->height; i++) {
        fseek(fg->file, pos, SEEK_SET);
        fseek(bg->file, pos, SEEK_SET);

        for (j = pos; j < (fg->width + pos); j++) {

            char b = getc(fg->file);
            char g = getc(fg->file);
            char r = getc(fg->file);
            char b_bg = getc(bg->file);
            char g_bg = getc(bg->file);
            char r_bg = getc(bg->file);

            char * tmp = (char*)&fgbgR[i * fg->width + (j - pos)];
            *tmp = r;
            tmp++;
            *tmp = r_bg;

            tmp = (char*)&fgbgG[i * fg->width + (j - pos)];
            *tmp = g;
            tmp++;
            *tmp = g_bg;

            tmp = (char*)&fgbgB[i * fg->width + (j - pos)];
            *tmp = b;
            tmp++;
            *tmp = b_bg;

        }
        pos = mx + pos;

    }

I have tried to swap out the image handling, and so far I have:

cv::Mat imageFG = cv::imread("test2.bmp", -1);
    cv::Mat imageBG = cv::imread("back.bmp", -1);

    //split into channels
    cv::Mat bgr[3];   //destination array
    cv::split(imageFG, bgr);//split source  

    cv::Mat bgrBG[3];   //destination array
    cv::split(imageBG, bgrBG);//split source  

    int sizeCv = imageFG.cols * imageFG.rows;
    int width = imageFG.cols;
    int height = imageFG.rows;

    short* fgbgRcv = new short[sizeCv];
    short* fgbgGcv = new short[sizeCv];
    short* fgbgBcv = new short[sizeCv];

    for (int i = 0; i < sizeCv; i++)
    {
        fgbgRcv[i] = bgr[2].data[i];
        fgbgGcv[i] = bgr[1].data[i];
        fgbgBcv[i] = bgr[0].data[i];
    }


    //add BOTH fg and BG to the matrix
    int i = 0;
    int j = 0;
    int pos = 0;

    for (i = 0; i < height; i++) {

        for (j = 0; j < width; j++) {

            char b = bgr[0].data[i + j];
            char g = bgr[1].data[i + j];
            char r = bgr[2].data[i + j];
            char b_bg = bgrBG[0].data[i + j];
            char g_bg = bgrBG[1].data[i + j];
            char r_bg = bgrBG[2].data[i + j];

            char * tmp = (char*)&fgbgRcv[i * width + (j)];
            *tmp = r;
            tmp++;
            *tmp = r_bg;

            tmp = (char*)&fgbgGcv[i * width + (j)];
            *tmp = g;
            tmp++;
            *tmp = g_bg;

            tmp = (char*)&fgbgBcv[i * width + (j)];
            *tmp = b;
            tmp++;
            *tmp = b_bg;

        }

    }

but the resulting image is scrambled. I can't quite get a handle on how to replicate the function. Where am I going wrong here? Thank you.

Loading two Mats into split short arrays?

I am trying to replace an existing function with openCv for image handling. This is the function:

ImageBMP::ImageBMP(char * filename) {
    this->filename = filename;
    this->height = 0;
    this->width = 0;
    this->valid = 1;
    this->datapos = -1;
    this->file = nullptr;
}

    ImageBMP* fg = new ImageBMP("test2.bmp");
    ImageBMP* bg = new ImageBMP("back.bmp");

short* fgbgR = new short[size];
    short* fgbgG = new short[size];
    short* fgbgB = new short[size];


    pos = fg->datapos;
    int mx = 3 * fg->width;
    switch (mx % 4)
    {
    case 1:
        mx = mx + 3;
        break;
    case 2:
        mx = mx + 2;
        break;
    case 3:
        mx = mx + 1;
        break;
    }

    std::cout << pos << std::endl;


    // Fill matrix for Foreground and Background
    int i = 0;
    int j = 0;
    for (i = 0; i < fg->height; i++) {
        fseek(fg->file, pos, SEEK_SET);
        fseek(bg->file, pos, SEEK_SET);

        for (j = pos; j < (fg->width + pos); j++) {

            char b = getc(fg->file);
            char g = getc(fg->file);
            char r = getc(fg->file);
            char b_bg = getc(bg->file);
            char g_bg = getc(bg->file);
            char r_bg = getc(bg->file);

            char * tmp = (char*)&fgbgR[i * fg->width + (j - pos)];
            *tmp = r;
            tmp++;
            *tmp = r_bg;

            tmp = (char*)&fgbgG[i * fg->width + (j - pos)];
            *tmp = g;
            tmp++;
            *tmp = g_bg;

            tmp = (char*)&fgbgB[i * fg->width + (j - pos)];
            *tmp = b;
            tmp++;
            *tmp = b_bg;

        }
        pos = mx + pos;

    }

I have tried to swap out the image handling, and so far I have:

cv::Mat imageFG = cv::imread("test2.bmp", -1);
    cv::Mat imageBG = cv::imread("back.bmp", -1);

    //split into channels
    cv::Mat bgr[3];   //destination array
    cv::split(imageFG, bgr);//split source  

    cv::Mat bgrBG[3];   //destination array
    cv::split(imageBG, bgrBG);//split source  

    int sizeCv = imageFG.cols * imageFG.rows;
    int width = imageFG.cols;
    int height = imageFG.rows;
 
    short* fgbgRcv = new short[sizeCv];
    short* fgbgGcv = new short[sizeCv];
    short* fgbgBcv = new short[sizeCv];

 for (int i (i = 0; i < sizeCv; i++)
    i++) {
        fgbgRcv[i] 

        char b = bgr[0].data[i];
        char g = bgr[1].data[i];
        char r = bgr[2].data[i];
        fgbgGcv[i] = bgr[1].data[i];
        fgbgBcv[i] = bgr[0].data[i];
char b_bg = bgrBG[0].data[i];
        char g_bg = bgrBG[1].data[i];
        char r_bg = bgrBG[2].data[i];

        char * tmp = (char*)&fgbgRcv[i];
        *tmp = r;
        tmp++;
        *tmp = r_bg;

        tmp = (char*)&fgbgGcv[i];
        *tmp = g;
        tmp++;
        *tmp = g_bg;

        tmp = (char*)&fgbgBcv[i];
        *tmp = b;
        tmp++;
        *tmp = b_bg;

    }


    //add BOTH fg and BG 

Then later, I need to recreate the matrix Mat from a buffer, which i am doing like this:

//back to cv::Mat
    unsigned char* compBuffer = new unsigned char[imageFG.cols * imageFG.rows * imageFG.channels()]; 

    int r = 0;
    int g = 1;
    int b = 2;
    for (int i = 0;
    int j = 0;
    int pos = 0;

    for (i = 0; i < height; i++) {

        for (j = 0; j < width; j++) {

            char size; i++)
    {           
        compBuffer[b] = outRGB[i].r;
        compBuffer[g] = outRGB[i].g;
        compBuffer[r] = outRGB[i].b;

        r += 3;
        b = bgr[0].data[i + j];
            char += 3;
        g = bgr[1].data[i + j];
            char r = bgr[2].data[i + j];
            char b_bg = bgrBG[0].data[i + j];
            char g_bg = bgrBG[1].data[i + j];
            char r_bg = bgrBG[2].data[i + j];

            char * tmp = (char*)&fgbgRcv[i * width + (j)];
            *tmp = r;
            tmp++;
            *tmp = r_bg;

            tmp = (char*)&fgbgGcv[i * width + (j)];
            *tmp = g;
            tmp++;
            *tmp = g_bg;

            tmp = (char*)&fgbgBcv[i * width + (j)];
            *tmp = b;
            tmp++;
            *tmp = b_bg;

    += 3;     
    }

    }
cv::Mat outMat = cv::Mat(imageFG.rows, imageFG.cols, CV_8UC3, compBuffer);

but Is this the resulting image fastest way to copy this data around to and from Mat? or is scrambled. I can't quite get there a handle on how to replicate the function. Where am I going wrong here? Thank you.better way?