accumulate and += on CV_32FC3 -- odd results

asked 2013-09-02 06:26:23 -0600

cdstahl gravatar image

I've been attempting to average several frames of video. The first attempt was to convert the input frame into a CV_32FC3, then use += with another Mat of CV_32FC3. I had then hoped to use the scale parameter of convertTo in order to remove saturated pixels in the conversion to CV_8U3C.

I was having issues with mid-valued pixels saturating. In this specific case, there was a light source in the webcam's image, so some pixels would be saturated, and others would be somewhat bright, and others dark due to the webcam. Still, none of the individual frames had the mid-intensity pixels saturated.

The first sign something was odd was that I didn't need to use the scale factor in convertTo after accumulating 32 images. I would have expected highly saturated output or overflows. Doing the scale by 1.0f/32 resulted in a very dark image. Likewise, attempting to use *= 1.0f/32 before the convertTo had the same results.

Finally, I decided to look at *max_element(img.begin<float>(),img.end<float>()) for one channel at each step of the summation. For this case, I got 510 at each step. This also seemed odd, as I was expecting 0.0 to 1.0. I then turned off the light source and retested. Oddly enough, I got values that did not monotonically increase to 510! That means that somehow (x+y) < x. The minimum value in the input 32FC3 was 0 in each step of the iteration.

Some sample maxes I got in the summation are: 290 292 304 320 304 318 ... The second 304 shouldn't be lower.

I managed to solve my problem by using accumulateWeighted(inputFrame, averageFrame, 1.0f/32). But it wasn't obvious why accumulating 32 frames then dividing by 32 would fail to produce the same result. Likewise, I'm still not sure what += and accumulate are actually doing. My guess would be (x+y)/2.

My question is -- what is x + y intended to do for Mat of type CV_32FC3?

edit retag flag offensive close merge delete