Ask Your Question
0

Same algorithm gives different results in OpenCV vs Octave/Matlab

asked 2014-04-26 13:21:58 -0600

Ralph058 gravatar image

updated 2014-04-30 01:52:41 -0600

berak gravatar image

Hi I run an algorithm that extracts points of light from an image. In Octave (an Open Source Matlab), I extract 7557 points and get an image that is about what I expect. In OpenCV, using line for line the same code in the executable, OpenCV gives 3196 and the image looks more like noise.

The only difference is the access of the pixels. In Octave, I use pix4=imgNIR(newRow, newCol). In OpenCV, I have tried pix4 = imgNIR.at<uchar>(newRow,newCol) and the equivalent extracting the row using rowNIR = imgNIR.ptr<uint>(newRow) and pix4 = (int)rowNIR(newCol).

As I need negative numbers in some intermediate results, I need 'int' or 'long' data type. (I've tried both.) In Octave, I use uint32.

I have been able to replicate the size issue in Octave to a degree. The 7557 becomes something around 4000.

I have tried imaging at various points with additional Mat files. The one place I need to, I get a segment fault. It appears that there are little or no exception handlers. I inadvertently tried to address outside of the rows. Rather than some kind of index size error, I get a segment fault. I've found a few other causes of segment faults, but they don't apply here.

In Octave, the resulting image is now continuous except where I either have a phase error in the dot position or the spots are too dark. In OpenCV, there are vertical bands every other column. The output image is supposed to be a ramp that contains the subpixel position information. If I were using floating point, it would be the column of the spot centroid plus a decimal. I convert it to integer by premultipying by a constant. I'm using 128, but anything greater than 16 would do. The result in Octave is a continuous ramp. In OpenCV, the values jump up and down across the image in no particular pattern.

I've used cout to print the row, col, and value int the row. Those results look OK. My best guess is that it has something to do with the replacement statement:

rowSpot[spotCol] =(unsigned long)testVar;

I'm using the pointer read writes. I'm getting similar results using .at:

imgSpots.at<long>(spotRow, spotCol)= testVar;

Although, with the latter, there seems to be two missing pixels in the banding rather than one with the pointer method.

Any suggestions or debug hints will be appreciated. Thanks Ralph

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
1

answered 2014-04-29 13:51:36 -0600

Ralph058 gravatar image

It appears an issue with 16U. I converted the Mat to 16S. It seems to work fine.

I don't have time to diagnose what the issue was. I was outputting unsigned numbers less than 16bits. I had changed the rescale to 64 and then 32 and still had 65535 in the output even though the largest number I found in printing the values was around 41000. The middle of the row, where a couple of the 65535 occurred, should have been no more than 20000 with the 128 multiplier.

I should probably report a bug report, but I still don't know if it was something I was doing.

Ralph

edit flag offensive delete link more

Question Tools

Stats

Asked: 2014-04-26 13:21:58 -0600

Seen: 686 times

Last updated: Apr 29 '14