1

The cv2.PCACompute function worked well in OpenCV 2.4 using the following syntax :

import cv2
mean, eigvec = cv2.PCACompute(data)

The function exists in OpenCV 3.1, but raises the following exception :

TypeError: Required argument 'mean' (pos 2) not found

The C++ documentation is not very helpful at explaining how I should call it from Python. I'm guessing that InputOutputArray arguments are now also mandatory arguments in the Python function signature, but I am unable to find a way to make them work.

Is there a way I can call it properly?

(Note: I know there are other ways I can run a PCA, and I'll probably end up with one of them. I'm just curious about how the new OpenCV bindings works.)

F.X.
  • 6,809
  • 3
  • 49
  • 71
  • If it helps, there was an old [question](https://stackoverflow.com/questions/8567704/opencv-pca-compute-in-python) that is similar to this problem you faced, where the same (and other) solution were given. – DarkCygnus Dec 05 '17 at 19:06

1 Answers1

5

Simple answer:

mean, eigvec = cv2.PCACompute(data, mean=None)

With details:

  1. Let search PCACompute the source first.Then find this:

    // [modules/core/src/pca.cpp](L351-L360)
    void cv::PCACompute(InputArray data, InputOutputArray mean,
                        OutputArray eigenvectors, int maxComponents)
    {
        CV_INSTRUMENT_REGION()
    
        PCA pca;
        pca(data, mean, 0, maxComponents);
        pca.mean.copyTo(mean);
        pca.eigenvectors.copyTo(eigenvectors);
    }
    
  2. OK, now we read the document:

    C++: PCA& PCA::operator()(InputArray data, InputArray mean, int flags, int maxComponents=0)
    Python: cv2.PCACompute(data[, mean[, eigenvectors[, maxComponents]]]) → mean, eigenvectors
    
    Parameters: 
        data – input samples stored as the matrix rows or as the matrix columns.
        mean – optional mean value; if the matrix is empty (noArray()), the mean is computed from the data.
    flags –
        operation flags; currently the parameter is only used to specify the data layout.
    
        CV_PCA_DATA_AS_ROW indicates that the input samples are stored as matrix rows.
        CV_PCA_DATA_AS_COL indicates that the input samples are stored as matrix columns.
    maxComponents – maximum number of components that PCA should retain; by default, all the components are retained.
    
  3. This to say,

    ## py
    mean, eigvec = cv2.PCACompute(data, mean=None)
    

    is equals to

    // cpp 
    PCA pca;
    pca(data, mean=noArray(), flags=CV_PCA_DATA_AS_ROW);
    ...
    
Kinght 金
  • 17,681
  • 4
  • 60
  • 74
  • Thank you, the fact that you had to pass `None` wasn't obvious at all in the docs, even those about `noArray()` :) – F.X. Oct 31 '17 at 09:04
  • 1
    The document says `mean – optional mean value; if the matrix is empty (noArray()), the mean is computed from the data.` So, just pass `None`. – Kinght 金 Oct 31 '17 at 09:26