ofxCvFloatImage with cvWatershed

hello,
I’m trying to use the cvWatershed function ( http://www.seas.upenn.edu/~bensapp/opencvdocs/ref/opencvref-cv.htm.

According the reference manual:

  
void cvWatershed( const CvArr* image, CvArr* markers );  
image  
    The input 8-bit 3-channel image.   
markers  
    The input/output 32-bit single-channel image (map) of markers.  
  

For the Markers i try to use a ofxCvFloatImage, according to the .h file comments:

_This is essentially an IPL_DEPTH_32F with one channel _

Problem is that when I run the programm a runtime error occurs with the following message:

OpenCV ERROR: Unsupported format or combination of formats (Only 32-bit, 1-channel output images are supported) in function cvWatershed, /Users/theo/Documents/CODE/__OPENFRAMEWORKS/SANDBOX/COMPILE_LIBRARIES/__openCV/openCV1.1PreCompile/cv/src/cvsegmentation.cpp(161)

I already checked the channels and depth of my cvFloatImage and they seem to be correct, now I’m a bit stuck where the error cames from. If I’m using _cvCreateImage( cvGetSize(img), IPL_DEPTH_32S, 1 ) _ everything works fine, but thats not the way I wanna go :wink:

theo has a fix for this:

http://forum.openframeworks.cc/t/strange-bug-with-haar-finder-and-opencv-1.1pre/1853/0

hmm,

not sure how this belongs to my problem atm. but maybe I will have a look later - I’m already sitting since the last 15 hours in front of this computer :roll: maybe I need some sleep before having another look.

tanks m9d

can you post the code that shows how you are calling the function?

Thanks!
Theo

hi,

I already altered the code to be more opencv like - it works now.

bascially what i did was the following:

  
  
  
ofImage				ofImg;  
ofxCvColorImage		cvColorImg;  
ofxCvGrayscaleImage         cvGrayImg;  
ofxCvFloatImage		cvMarker;  
  
  
ofImg.loadImage("images/"+imgFile);  
	  
cvColorImg.allocate(ofImg.getWidth(), ofImg.getHeight());  
cvGrayImg.allocate(ofImg.getWidth(), ofImg.getHeight());  
cvMarker.allocate(ofImg.getWidth(), ofImg.getHeight());  
  
cvColorImg.setFromPixels(ofImg.getPixels(), ofImg.getWidth(), ofImg.getHeight());  
  
cvGrayImg = cvColorImg; // conversation via operator overloading  
  
/*  
... contur detection in the cvGrayImg  
... writing these conturs into cvMarker, using cvDrawContours for that  
*/  
  
cvWatershed( cvColorImg.getCvImage(), cvMarker.getCvImage());  
  
/*  
... using cvMarker (holds now the new watershed image) to do image segmentation  
*/  
  
  

… gives the mentioned runtime error

If you look at the docs:
http://www.cs.indiana.edu/cgi-pub/oleyk-…-vWatershed

You see it says you have to fill the values with positive indicies >0 for the float image. So that could be the reason for the problem.

Also as a note - to get the ofxOpenCv Image to reflect the changes to it by using an external cv function you need to change
image.bPixelsAreDirty to true.

Currently it is a protected variable so you might need to move it from protected to public in ofxCvImage

We should fix this soon - ie have a image.refreshPixelsFromCv(); or something.

Theo

Theo, there is already: flagImageChanged() :slight_smile: I just noticed this today.

The problem you’re running into with cvWatershed is that it doesn’t take an IPL_DEPTH_32F (1-channel, 32-bit float image) for the markers, but an IPL_DEPTH_32S (1-channel 32-bit signed integer image). This is because the markers have values like 1, 2, 3, etc.

You’ll have to create your own IplImage of this type manually, as ofxOpenCv doesn’t currently have a wrapper for it.

yeah, already did that - it’s a bit messy but it works.

thanks for the tips.
m9dfukc

Theo, there is already: flagImageChanged() I just noticed this today.

yeah me too - I was going to add it to stefans list and then I saw it - can’t believe I had been hacking ofxOpenCv :slight_smile: