I'm upgrading to OpenCV 3 and using the UMat T_API OpenCL container instead of Mat.
It appears that drawing functions like rectangle(Mat img, ...) don't have a UMat overload. I would like to work in the UMat world as much as possible for drawing on frames without having to convert UMat back to Mat for drawing and displaying.
Can anyone give me the most efficient way to draw a rectangle on a UMat? Or do I have to convert back to Mat to draw on and display?
Unfortunately, there is no way to draw something on UMat without transferring data from GPU memory.
You may use following scheme to do drawings:
cv::Mat draw_img = img.getMat(cv::ACCESS_WRITE);
cv::rectangle(draw_img, ...);
draw_img.release();
Please note that getMat(cv::ACCESS_WRITE) requires synchronization. So in order to get maximum benefits of GPU processing, it will be better to avoid drawing operations or group it into one block.
Related
I want to change some code in OpenCV to use cv::UMat instead of cv::Mat to get extra speed with OpenCL/GPU when working with images.
But what I used to access image data directly by pointer doesn't work anymore, e.g:
cv::Vec3b* imageP = image.ptr<cv::Vec3b>(y)
where image is a cv::Mat and y is the image line offset, because the Ptr() method doesn't exist for UMat.
What is the correct syntax with a UMat? Is it even possible ?
Thank you.
I searched a lot and I understand there is no simple solution, but copying back and forth between Mat and UMat is soooo slow :(
I have a gray image (648*488 pixels) and I want to get the coordinates of the pixels above a threshold, I need to be really fast doing this so I want to know if there is a function in opencv to do this.
You could start with the OpenCV forEach method in the Mat class.
It uses one of several parallel frameworks for multithreading.
If it has to be even faster, access the memory directly and compute the threshold for several pixels with SIMD instructions at the same time.
You can also use GPUs (Cuda / OpenCL).
Recently started playing around with OpenCV, trying that SURF algorithm, that is really slow on CPU, and does not work with color images on GPU (has an assertion that checks for type==CV_8UC1), and converting images to grayscale gives some pretty bad results.
I'm wondering if there is a colored implementation on gpu in OpenCV, somewhere else, or if there is some kinda tricky workaround like doing the algorithm on all 3 channels and then magically merging them?
Thanks.
There's no special handling of color images in OpenCV's non-GPU version of SURF; the code shows that it just calls cvtColor(img, img, COLOR_BGR2GRAY) if it gets an image with more than one channel.
You might try converting the image to HSV and using one or more of the H, S, and/or V channels. More discussion at this question.
I'm using OpenCV to convert image data captured using an IDS uEye camera into a useful format, using the following code:
IplImage* tmpImg = cvCreateImage(cvSize(width,height),IPL_DEPTH_8U,3);
tmpImg->imageData = pFrameBuffer[k];
frame = cv::cvarrToMat(tmpImg);
This works perfectly - I can then use imwrite(filename,frame); further downstream to write the processed images out as a sensible format. I would ideally like to be able to save the RGB channels as separate 'grayscale' image files, but I don't understand the OpenCV documentation regarding single-channel operations. Can anyone suggest a means of accomplishing this? Preferably it's not overly computationally expensive (looping over an image pixel-by pixel isn't an option - I'm working with 60-230fps video at up to 1280x1064, and all the processing has to be done at the point of capture).
Running the latest Debian Testing if that makes any difference (I don't think it should).
Once you have a cv::Mat object it's pretty simple:
std::vector<cv::Mat> grayPlanes;
cv::split(frame, grayPlanes);
cv::imwrite("blue.png", grayPlanes[0]);
cv::imwrite("green.png", grayPlanes[1]);
cv::imwrite("red.png", grayPlanes[2]);
The split function can directly write to a standard vector and you don't really have to think about memory management and other stuff.
Assume that I have a code which is written in C++ and uses Mat to hold images.
I want to change all Mats to UMat so the application runs on GPU as well on CPU (If I turn off GPU processing by calling ocl::setUseOpenCL(false);)
But I am wondering if I do this, is there any performance changes?
so in summery, if I have a code that uses Mat, if I change all Mats to UMats, is there any performance difference (When not running on GPU)?
Edit1
to clear the scope of question, Let me reword it:
why should not I use uMat instead of Mat assuming I am not using GPU?
When using UMat, opencv utilises Transparent API to use additional hardware attached. So, by turning off GPU processing you shouldn't expect a speedup.