Question

I have a frame and want to put it in on a bigger image in openCV using openCL type oclMat. But code below gives me black frame result:

capture.read(fMat); // frame from camera or video
oclMat f; f.upload(fMat);
oclMat bf(f.rows*2, f.cols*2, f.ocltype()); // "bf"-big frame
oclMat bfRoi = bf(Rect(0, 0, f.cols, f.rows));
f.copyTo(bfRoi); // something wrong here
// label 1
bf.download(fMat);
Mat bf2; bf.convertTo(bf2, fMat.type()); // this convert affects to nothing
imshow("big frame", bf2);

So I have to add at the "label 1" place "oclMat->Mat" conversion and back "Mat->oclMat":

Mat fTmp, bfTmp(Size(bf.cols, bf.rows), fMat.type());
f.download(fTmp);
fTmp.convertTo(fTmp, fMat.type()); // it is necessary due to assert(channels() == CV_MAT_CN(dtype))
fTmp.copyTo(bfTmp(Rect(0, 0, fTmp.cols, fTmp.rows)));
bf.upload(bfTmp);

It works but takes too much time and code looks sad. Is it possible to do the same thing staying in the term of oclMat only (without forward and back conversion)?

Was it helpful?

Solution

Well, I have been searching wrong place: operations_on_matrices instead of image_filtering. So at least one way to do it inside ocl exists -- copyMakeBorder(...). So my approach now is:

capture.read(fMat); // frame from camera or video
oclMat f; f.upload(fMat);
oclMat bf(f.rows*2, f.cols*2, f.ocltype()); // "bf"-big frame from somewhere
// new approach here
oclMat bf2(bf.rows, bf,cols); // temp frame of the same size as big frame
copyMakeBorder(f, bf2, 0, bf2.rows-f.rows, 0, bf2.cols-f.cols, BORDER_CONSTANT, Scalar(0,0,0)); // here it is! any position possible by changing border sizes (remember about mask)
oclMat mask(bf.rows, bf.cols, CV_8UC1); // bw mask to keep part of big frame unchanged
mask = Scalar(0); mask(Range(0, f.rows), Range(0, f.cols)) = Scalar(1); // "draw" rectangle
bf2.copyTo(bf, mask);
// label 1
bf.download(fMat);
imshow("big frame", fMat);

I am not sure if it is the best way, but at least it works.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top