Domanda

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

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top