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;
short* fgbgRcv = new short[sizeCv];
short* fgbgGcv = new short[sizeCv];
short* fgbgBcv = new short[sizeCv];
for (i = 0; i < sizeCv; i++) {
char b = bgr[0].data[i];
char g = bgr[1].data[i];
char r = bgr[2].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;
}
Then later, I need to recreate the 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; i < size; i++)
{
compBuffer[b] = outRGB[i].r;
compBuffer[g] = outRGB[i].g;
compBuffer[r] = outRGB[i].b;
r += 3;
b += 3;
g += 3;
}
cv::Mat outMat = cv::Mat(imageFG.rows, imageFG.cols, CV_8UC3, compBuffer);
Is this the fastest way to copy this data around to and from Mat? or is there a better way?
what are you trying to achieve here ? what is the context ?
Hi, thanks for getting back to me. I am trying to replace the
// Fill matrix for Foreground and Background
section above. What it seems to be doing is combining the two sets of image data. I should probably try to understand what it is doing a bit better before i try to re-code it really!no, try to explain better, please !
what does it mean, exactly ?
most likely, what you want, can (and should !) be done without writing ANY loops.
also, are you sure, your images are both 16bit 3 channel ?
I am trying to understand the function, but am confused here
char * tmp = (char*)&fgbgR[i * fg->width + (j - pos)];
it looks like he makes a short[] then assigns the data from both images to it.yea, but why ?
It is passed into a cuda chroma keying function, which spits out the composited image. I have it working now, will update the question. is this possible without the loops? Thanks again for your patience!