I need to use ofVideoGrabber as opposed to OpenCV to VideoCapture. In previous code I wrote I used Mat::data to pull the actual pixel of the frame as a uchar* … and reading through the ofVideoGrabber::getPixels() call I see that it too returns a unsigned char*.
However, when it comes time to convert the incoming from ofVideoGrabber from RGB to BGR format I get a failure. The code I am using is as follows:
The call to this same function using OpenCV is successful. The call to this function from ofVideoGrabber.getPixels() fails rBuffer, gBuffer and bbuffer for access violations/memory not accessible.
Any and all comments and insights from the community would be greatly appreciated.
Hi,
the getPixels() method returns a reference to the ofPixels object. It has been this way for quite a while. To get acces to the uchar pointer call grabber.getPixels().getData()
Wrapping grabber.getPixels() with the { } is at least unsafe if it actually compiles.
I recommend you to change your functions arguments to have const ofPixels& srcs instead of const std::vector<uint8_t*>& srcs
You’ll need to check what’s going on in the function’s internals which I think have at least one extra for loop, the first one.
I rewrote my code to conform to your advice and it is sound. Thanks. However, I am required to RESIZE my image … and as such do not know what is the OF way of doing this. I checked out ofImage and still somewhat lost as to how to effect 1) taking my frame from ofVideoGrabber; 2) resizing it from 640x480 to 224x224; swapping it from RGB to BGR … and doing so without necessarily relying on OpenCV to do this.
Should you or others have any insights on pulling this off within OF I would appreciate hearing from you.
As for your question, even when you could do everything in place -destructively modifying the ofVideoGrabber pixels- it is not a good idea, so lets start by copying its pixels.
// ofVideoGrabber grabber; // Declared elsewhere
//Assuming we have correctly initialized grabber
If you simply want to process the pixels and not display these do the following.
ofPixels pix = grabber.getPixels(); //this will create a copy
pix.resize(224x224);//resizing
pix.swapRgb(); //fortunately for you, ofPixels has this function that does what you are looking for.
If you want to draw this it might be easier to use an ofImage instance instead.
// ofImage img; //declared elsewhere, probably in the ofApp.h file.
img.setFromPixels(grabber.getPixels());
img.getPixels().resize(224, 224);//or whichever size you might want.
img.getPixels().swapRgb();
img.update();
Thats all. hope this helps. if you want to know whats going on with the pixels just go and read the actual code of each class.
@roymacdonald … thanks for your kind and helpful words. I accomplished what I required to do by switching over to OpenFrameworks from OpenCV highgui.
One final question I have … is there a way to pull an individual plane of pixels from an image? More precisely, given that I have an image with interleaved RGB values, how do I pull the plane of R-pixels - only the R-values from the pixels - is there a construct in OF that enables one to do this?
I think you are looking for getChannel(0) in ofPixels. This is the explanation on the ofPixels.h:
/// \brief Get all values of one channel
///
/// For instance, the Red pixel values, from the
/// ofPixels object, this gives you a grayscale representation of the
/// specific channel
///
/// ~~~~{.cpp}
/// // Get red pixels
/// ofPixels rpix = pix.getChannel(0);
/// // Get green pixels
/// ofPixels gpix = pix.getChannel(1);
/// // Get blue pixels
/// ofPixels bpix = pix.getChannel(2);
/// ~~~~
ofPixels_<PixelType> getChannel(size_t channel) const;