kylemcdonald / ofxCv

Alternative approach to interfacing with OpenCv from openFrameworks.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Allocating ofImage as cv::Mat reference

noio opened this issue · comments

In the README it says to use an ofImage to wrap a cv::Mat in stead of calling drawMat. So, the code I'm using is somewhat like the following (albeit gathered from different places).

frame_screen = toCv(frame_screen_im);
cv::resize(frame, frame_screen, cv::Size(screen_width, screen_height), 0, 0, cv::INTER_NEAREST);
frame_screen_im.update();
frame_screen_im.draw()

This gives me an unallocated texture when I draw().

My other code does work:

cv::resize(frame, frame_screen, cv::Size(screen_width, screen_height), 0, 0, cv::INTER_NEAREST);
toOf(frame_screen, frame_screen_im);
frame_screen_im.update();
frame_screen_im.draw()

But this is allocating a texture every frame in toOf, doesn't it? Why does the first snippet not work? Does cv::resize break the connection of ofImage to the Mat somehow?

Edit: I realize this is most likely not an issue with ofxCv, but an answer to this would much increase my understanding of the addon :)

hey! i think what might be going on with the first chunk is this:

  1. your frame_screen_im is unallocated
  2. when you call toCv() you are making frame_screen wrap empty image data
  3. when you call cv::resize(), opencv resizes frame_screen to fit the new data. except opencv can't tell frame_screen_im to also resize itself, because OF and opencv don't know about each other. so the connection is "broken" like you say. OF keeps pointing to the same place, but the Mat is now bigger and OF has no clue.

but it's hard to say without seeing the full code.

usually you don't need to worry about allocation with ofxCv, but in cases like this where OF and opencv are using the same memory, it's essential.

the alternative is to add an allocate() at the beginning of your code. frame_screen.allocate(screen_width, screen_height, OF_IMAGE_COLOR);

then the first case should work fine.

actually, there is nothing wrong with the second case. the second case does not re-allocate a texture because toOf() calls imitate(img, mat), which only re-allocates if the size has changed (which will happen on the first frame, but no following frames unless your screen size changes). so the result of toOf() will be no re-allocation, just a call to pixels.setFromExternalPixels() which is a fast shallow copy.

which one you want to use is a question of how you want to think about your ofImages and Mats. my preference is usually for whatever technique uses less code, so in this case i might use the second one because it doesn't need an extra call to allocate().

and yes, not an issue, but happy to share some notes for clarification :) i ask in return that you edit the readme to make it more clear, if you have a moment.