OpenCV coding skills (1)

CV_Assert( (npoints = someMat.checkVector(2, CV_32F, true)) >= 0 );

What does checkVector do?

//! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise
int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const;

Before diving into the code, we need to know the below things:
1. Mat.depth(): what each element in Mat stands for,such as int, float, or double, in opencv style, those are CV_8U, CV_8S, CV_16U and so on.
2. Mat.isContinous(): normal check for Mat data.
3. Mat.dims: the array dimensionality, >= 2.
4. Mat.rows and Mat.cols: the number of rows and columns or (-1, -1) when the array has more than 2 dimensions.
5. Mat.channels(): how many number each element in Mat has.
6. Mat.size and size.p
7. Mat.step and step.p
8. Mat.total(): total number of array elements.

OK, let’s have a look at the function inside.

int Mat::checkVector(int _elemChannels, int _depth, bool _requireContinuous) const
{
    return 
        (depth() == _depth || _depth <= 0) &&
        (isContinuous() || !_requireContinuous) &&
        ((dims == 2 && (((rows == 1 || cols == 1) && channels() == _elemChannels) ||
                        (cols == _elemChannels && channels() == 1))) ||
         (dims == 3 && channels() == 1 && size.p[2] == _elemChannels && (size.p[0] == 1 || size.p[1] == 1) &&
         (isContinuous() || step.p[1] == step.p[2]*size.p[2])))
    ? (int)(total()*channels()/_elemChannels) : -1;
}

The code is in fact a && b && c. Use && and || instead of a lot of if-else, cool! a is for _depth, b is for _requireContinuous, and c is for _elemChannels.

a: (depth() == _depth || _depth <= 0), check depth. If _depth <=0, that mean don’t check depth.

b: (isContinuous() || !_requireContinuous): common data check. Same trick used in previous.
c:

((dims == 2 && 
   (((rows == 1 || cols == 1) && channels() == _elemChannels) ||
    (cols == _elemChannels && channels() == 1) )) 
 ||
 (dims == 3 && 
   channels() == 1 && 
   size.p[2] == _elemChannels && 
   (size.p[0] == 1 || size.p[1] == 1) &&
   (isContinuous() || step.p[1] == step.p[2]*size.p[2])))

From the above code, we know that:

  1. If Mat is 2D(dims=2, standing for an image for most case), we can use cols and rows.
  2. If Mat is 3D or more, Mat is not an image. Cols and rows make no sense. So we need to use Mat.step and Mat.size to access element.

Besides, checkVector returns how many elements are there in the Mat.

return [check] ? (int)(total()*channels()/_elemChannels) : -1;

For most case, channels() == _elemChannels, just like the second line of c, but for some other cases, channels()=1, _elemChannels is in other dimension. So this sentence works well.

So, what does

CV_Assert( (npoints = someMat.checkVector(2, CV_32F, true)) >= 0 );

do?

  1. Check whether someMat stores data in the assumed way.
  2. Get how many element(points) in someMat.
  3. CV_Assert is very useful for strong code, which should be used frequently.

你可能感兴趣的:(opencv源码)