ofxCvGrayscaleImage from ofTexture

Hi all!

Im using ofxPS3EyeGrabber to get two cameras working simultaniously. I already have both images, but now i want to make blob detention on them using ofxOpenCv.
Now i need to get an ofxCvGrayscaleImage from an ofTexture. Here is what i have:

 if (videoGrabbers[i]->isFrameNew())
        {
            videoTextures[i].loadData(videoGrabbers[i]->getPixelsRef());
        }

What i need is something like this:

grayImg.setFromPixels(videoTextures[i]->getPixelsRef());

But theres no getPixelsRef() in ofTexture.
Thanks!

a texture is memory in the graphics card and reading it back to an ofPixels which is in the computers memory would be slow. the easiest in your case would be to directly copy the pixels from the grabber to the cv image like:

grayImg.setFromPixels(videoGrabbers[i]->getPixelsRef());

if you really need to copy the info from a texture into a cv image then you can read it back thoryugh an ofPixels like:

tex.readToPixels(pixels);
grayImg.setFromPixels(pixels);

but that’s usually really slow.

Thanks @arturo!!
I’ve already tried that. But here is what i get:

if (videoGrabbers[i]->isFrameNew())
        {
            videoTextures[i].loadData(videoGrabbers[i]->getPixelsRef());
		grayImg.setFromPixels(videoGrabbers[i]->getPixelsRef());
        }

Some weird noise. Im i missing something important?

Get the same noisy image using ofPixels.

videoTextures[i].readToPixels(pixels);
grayImage.setFromPixels(pixels);

oh, ok yes the image from the video camera is a color image and you are trying to put it in a grayscale one, you need to convert it first. take a look at the openCvExample where it shows how to do this conversion

With a color image i get the same. In that example the only thing it does is:

colorImg.setFromPixels(vidPlayer.getPixels(), 320,240);
grayImage = colorImg;

Exactly what i have :confused:

I think the problem may be in the videoGrabber, since it isnt the usually ofVideoGrabber. Im using ofxPS3EyeGrabber, so what i have is:

std::vector<std::shared_ptr<ofxPS3EyeGrabber> > videoGrabbers;

setup:

std::shared_ptr<ofxPS3EyeGrabber> videoGrabber = std::shared_ptr<ofxPS3EyeGrabber>(new ofxPS3EyeGrabber());
videoGrabber->listDevices();
videoGrabber->setDeviceID(i);
videoGrabber->setDesiredFrameRate(camFrameRate);
videoGrabber->initGrabber(camWidth, camHeight);

Any sugestions on a work around? thanks!

with OfxCV you can use convertColor()

I did not test it but try something like:
convertColor(colorImg.getPixelsRef(), grayImage.getPixelsRef(), CV_RGB2GRAY);

Still with all that noise. My output windows shows this error:

[warning] ofxCvColorImage: copy constructor: source image not allocated

Any ideas?

Hi,
I don’t know why but I got it working with ofImage but not with ofxCvColorImage

Here is a woking example:

 ofImage img;
 ofxCvGrayscaleImage  grayImage;

grayImage.allocate(320,240);
if (vidGrabber.isFrameNew())
{
    img.setFromPixels(vidGrabber.getPixelsRef());
    ofxCv::convertColor(img.getPixelsRef(), grayImage.getPixelsRef(), CV_RGBA2GRAY);
    grayImage.flagImageChanged();
}

grayImage.draw(0,0);

Just wanted to add that @talaron’s solution worked for me, without much of a performance penalty. Thanks dude. Although, like you, I’m also still confused as to why.

Hi. Following the official document. It works for me.
https://openframeworks.cc/documentation/ofxOpenCv/ofxCvGrayscaleImage/

//in app.h
	ofxCvColorImage Cam;
	ofxCvGrayscaleImage  grayImage;
//in draw method
void ofApp::draw(){
	Cam.setFromPixels(cam.getPixels());
	grayImage = Cam;
	grayImage.draw(0, 0);
}