Ask Your Question
1

meanStdDev seems to have a bug? Or am I using it wrong?

asked 2018-01-21 20:11:22 -0600

hn_88 gravatar image

updated 2018-01-21 22:42:57 -0600

When I use meanStdDev for an array with more than a million elements (m = 1228800x1 matrix, by reshaping a single channel 1280x960 image), I seem to get an overflow or something like that.

Code snippet:

m=cvarrToMat(img, true);
m=m.reshape(0,1); //makes m a 1228800x1 matrix
m.copyTo(m1);
meanStdDev(m1, meanframe1, stdframe1);

If I use a 128x96 matrix as an input, I get values like meanframe(0)=3067.9 stdframe1(0)=107.072 which seem to be correct for a dark frame from a cmos camera.

But if I use a 1280x960 image as input under the same conditions, I get meanframe(0)=-454.69 stdframe1(0)=14832.8 which is absolutely wrong - negative number for mean!

Additional info:

meanframe1=mean(m1);

gives the correct answer even for large matrices. So, meanStdDev along seems to be the culprit....

More additional info:

my own code for StdDev also gives correct results,

meanframe1=mean(m1);
double dstddev = 0.0;
                                    double dmean = meanframe1(0); // only one channel

                                    for (int i = 0; i < w*h; i++)
                                    {
                                        dstddev += (dmean - m1.at<ushort>(i)) * (dmean - m1.at<ushort>(i));
                                    }

                                    dstddev = sqrt(dstddev / (w*h));

                                    std::cout<<"mean="<<meanframe1(0)<<std::endl;
                                    std::cout<<"stddev="<<dstddev<<std::endl;
edit retag flag offensive close merge delete

Comments

"I use meanStdDev for an unsigned int array" -- not supported from opencv. also, using cvarrToMat raises a red flag here. show us, how you construct that, please !

berak gravatar imageberak ( 2018-01-21 21:51:27 -0600 )edit

cvarrToMat, from https://docs.opencv.org/2.4/modules/core/doc/operations_on_arrays.html#Mat%20cvarrToMat

That part is fine, I use

if(img == NULL)
                {
                    img = cvCreateImageHeader(cvSize(w,h),bpp,1);
                    img->imageData = (char *)ImgData;
                }
hn_88 gravatar imagehn_88 ( 2018-01-21 22:01:09 -0600 )edit

and after that,

m=cvarrToMat(img, true);
hn_88 gravatar imagehn_88 ( 2018-01-21 22:04:55 -0600 )edit
1

you should NOT use anything like that, from the (since 2010) deprecated C-api.

but this does not explain: "I use meanStdDev for an unsigned int array". (again, only signed ints are supported, and it's entirely unclear, where your data comes from)

berak gravatar imageberak ( 2018-01-21 22:06:50 -0600 )edit

Sorry for the confusion. My data comes from a QHY camera. (The deprecated code is from a QHY sample :) The code for getting the data is as follows.

unsigned char *ImgData;
IplImage *img = NULL;
length = GetQHYCCDMemLength(camhandle);


        if(length > 0)
        {
            printf("GetQHYCCDMemLength success!\n");
            ImgData = (unsigned char *)malloc(length);
            memset(ImgData,0,length);
            printf("memset success!\n");
        }
// initialize camera etc, then

ret = GetQHYCCDLiveFrame(camhandle,&w,&h,&bpp,&channels,ImgData);

That populates ImgData, in my case since I have used the camera in 16bit mode, with unsigned 16 bit numbers.

hn_88 gravatar imagehn_88 ( 2018-01-21 22:14:51 -0600 )edit
1

Have edited my question to remove the "unsigned int" from the array, since that may be incorrect :)

hn_88 gravatar imagehn_88 ( 2018-01-21 22:21:22 -0600 )edit

2 answers

Sort by ยป oldest newest most voted
1

answered 2018-01-22 04:21:21 -0600

berak gravatar image

updated 2018-01-22 04:22:53 -0600

since we cannot reproduce your hardware setup, here's a small testcase:

Mat m(960,1280,CV_16U);
randn(m,10000, 500);
Scalar M,D;
meanStdDev(m,M,D);
cout << M(0) << " " << D(0) << endl;
Mat m2 = m.reshape(0,1);
meanStdDev(m2,M,D);
cout << M(0) << " " << D(0);


10000.5 500.032
10000.5 500.032

so, probably not a meanStdDev bug, but a problem with your data acquisition.

1st thing to do: get rid of the IplImage !

Mat image(960, 1280, CV_16U); // allocate data
// now read it in directly
ret = GetQHYCCDLiveFrame(camhandle,&w,&h,&bpp,&channels, image.data);
edit flag offensive delete link more
1

answered 2018-01-24 04:13:43 -0600

hn_88 gravatar image

updated 2018-01-24 04:14:09 -0600

Thanks Berak. On my opencv version 3.3.1 , I got outputs

10000.5 500.032
-485.257 24231.6

So probably my opencv version has this bug :)

My code was, as you posted,

Mat mtest(960,1280,CV_16U);
randn(mtest,10000, 500);
Scalar M,D;
meanStdDev(mtest,M,D);
std::cout << M(0) << " " << D(0) << std::endl;
Mat m2t = mtest.reshape(0,1);
meanStdDev(m2t,M,D);
std::cout << M(0) << " " << D(0);
edit flag offensive delete link more

Comments

Upgraded to OpenCV 3.4.0 release from opencv.org, still I get the same bug! With the test code as listed above, I still get

10000.5 500.032
-485.257 24231.6

Should I post this as a new question?

hn_88 gravatar imagehn_88 ( 2018-01-25 22:22:14 -0600 )edit

Downgraded to 2.4.9.1+dfsg-1.5ubuntu1 and found that the bug is not present for this 2.4.9 version. Posted this as a bug report at github.

hn_88 gravatar imagehn_88 ( 2018-01-26 02:27:30 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2018-01-21 20:11:22 -0600

Seen: 1,911 times

Last updated: Jan 22 '18