IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Calcul scientifique Python Discussion :

Python numpy et fft


Sujet :

Calcul scientifique Python

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    50
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2004
    Messages : 50
    Points : 39
    Points
    39
    Par défaut Python numpy et fft
    Bonjour,

    Je n'arrive pas a obtenir les meme resultats que la doc pour les meme donnees :
    http://docs.scipy.org/doc/numpy/refe...numpy.fft.fft2

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    >>> a = np.mgrid[:5, :5][0]
    >>> a
    array([[0, 0, 0, 0, 0],
           [1, 1, 1, 1, 1],
           [2, 2, 2, 2, 2],
           [3, 3, 3, 3, 3],
           [4, 4, 4, 4, 4]])
    >>> np.fft.fft2(a)
    array([[ 50.0 +0.j        ,   0.0 +0.j        ,   0.0 +0.j        ,
              0.0 +0.j        ,   0.0 +0.j        ],
           [-12.5+17.20477401j,   0.0 +0.j        ,   0.0 +0.j        ,
              0.0 +0.j        ,   0.0 +0.j        ],
           [-12.5 +4.0614962j ,   0.0 +0.j        ,   0.0 +0.j        ,
              0.0 +0.j        ,   0.0 +0.j        ],
           [-12.5 -4.0614962j ,   0.0 +0.j        ,   0.0 +0.j        ,
              0.0 +0.j        ,   0.0 +0.j        ],
           [-12.5-17.20477401j,   0.0 +0.j        ,   0.0 +0.j        ,
              0.0 +0.j        ,   0.0 +0.j        ]])
    >>>
    en c++, en utilisant OpenCV j'ai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    double a[] = {
    	            0, 0, 0, 0, 0,
                    1, 1, 1, 1, 1,
                    2, 2, 2, 2, 2,
                    3, 3, 3, 3, 3,
                    4, 4, 4, 4, 4
                   };
    CvMat *Ma = cvCreateMat(5, 5, CV_64FC1);
    cvDFT(Ma, Ma, CV_DXT_FORWARD, 0);
    >>
    [ 50      0 0 0 0 ]
    [ -12.5   0 0 0 0 ]
    [ 17.2048 0 0 0 0 ]
    [ -12.5   0 0 0 0 ]
    [ 4.0615  0 0 0 0 ]
    est-ce que mon code c++ fais bien la meme chose que mon code python ? Quelqu'un peut m'expliquer pourquoi mes deux resultats different ?

    Merci d'avance !

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    723
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 723
    Points : 923
    Points
    923
    Par défaut
    Dans ton code C, si je ne m'abuse, nulle part tu ne donnes les valeurs de a à Ma.
    Après, il y aura certainement une différence due au typage, vu qu'en C ta matrice contient des double (donc des réels), tu n'auras que la partie réelle des complexes que te donne Python.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    50
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2004
    Messages : 50
    Points : 39
    Points
    39
    Par défaut
    oui, j'ai ete un peu vite, voila mon code C complet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
      double a[] = {
    	            0, 0, 0, 0, 0,
                    1, 1, 1, 1, 1,
                    2, 2, 2, 2, 2,
                    3, 3, 3, 3, 3,
                    4, 4, 4, 4, 4
                   };
     
      CvMat *Ma = cvCreateMat(5, 5, CV_64FC1);
      Ma->data.db = a;
      cvDFT(Ma, Ma, CV_DXT_FORWARD, 0);
     
      printMatrix(a, 5, 5);
    le resultat est toujours different du code python meme si je ne prends que la partie reelle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> real(fft.fft2(mgrid[:5, :5][0]))
    array([[ 50. ,   0. ,   0. ,   0. ,   0. ],
           [-12.5,   0. ,   0. ,   0. ,   0. ],
           [-12.5,   0. ,   0. ,   0. ,   0. ],
           [-12.5,   0. ,   0. ,   0. ,   0. ],
           [-12.5,   0. ,   0. ,   0. ,   0. ]])
    maintenant je me dit que c'est peu etre un probleme openCV et non un probleme python vu que je ne suis pas le seul a avoir eu le probleme (http://sci.tech-archive.net/Archive/.../msg00091.html)

    Ma question reste ouverte ^^ je vais voir du cote du forum opencv aussi

    merci d'avance

  4. #4
    Membre habitué

    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 35
    Points : 185
    Points
    185
    Par défaut
    Bonjour,

    Si tu veux être sûr et certain du résultat de ta FFT en Python, utilise plutôt PyIMSL Studio. Idem pour tout autre méthode mathématique et statistique proposée par ce produit.

    Tu éviteras de te perdre en conjectures sur la documentation, l'implémentation, etc...

    - SebGR

  5. #5
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Comme l'a écrit oiffrig, vu que les éléments de la matrice Ma sont de type "réel" , elle n'est apte qu'à enregistrer des valeurs réelles.

    Bien que je ne saurais expliquer le mécanisme en détail, il est clair qu'à cause de cela les valeurs de la première colonne obtenue en C++
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [ 50      0 0 0 0 ]
    [ -12.5   0 0 0 0 ]
    [ 17.2048 0 0 0 0 ]
    [ -12.5   0 0 0 0 ]
    [ 4.0615  0 0 0 0 ]
    sont les parties entières et parties imaginaires non nulles se succédant dans la première colonne obtenue en Python
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    array([[ 50.0 +0.j        ,   0.0 +0.j   ......          
     
    [-12.5+17.20477401j,   0.0 +0.j    ......                
     
    [-12.5 +4.0614962j ,   0.0 +0.j   ......          
     
    [-12.5 -4.0614962j ,   0.0 +0.j       ......            
     
    [-12.5-17.20477401j,   0.0 +0.j   ......
    du moins celles des 3 premières lignes.





    En cherchant un peu, j'ai trouvé ceci:


    Matrix data types:

    CV_<bit_depth>(S|U|F)C<number_of_channels>

    S = Signed integer
    U = Unsigned integer
    F = Float

    E.g.: CV_8UC1 means an 8-bit unsigned single-channel matrix,
    CV_32FC2 means a 32-bit float matrix with two channels.


    http://www.cs.iit.edu/~agam/cs512/le...00000000000000



    The class cvMat() represents a 2D numerical array that can act as a matrix (and further it’s referred to as a matrix), image, optical flow map etc. It is very similar to CvMat type from earlier versions of OpenCV, and similarly to CvMat, the matrix can be multi-channel, but it also fully supports ROI mechanism, just like IplImage.

    There are many different ways to create cvMat() object. Here are the some popular ones:



    using create(nrows, ncols, type) method or the similar constructor Mat(nrows, ncols, type[, fill_value]) constructor. A new matrix of the specified size and specifed type will be allocated. type has the same meaning as in cvCreateMat method, e.g. CV_8UC1 means 8-bit single-channel matrix, CV_32FC2 means 2-channel (i.e. complex) floating-point matrix etc:



    // make 7x7 complex matrix filled with 1+3j.
    cv::Mat M(7,7,CV_32FC2,Scalar(1,3));
    // and now turn M to 100x60 15-channel 8-bit matrix.
    // The old content will be deallocated
    M.create(100,60,CV_8UC(15));

    http://opencv.willowgarage.com/docum...tructures.html


    Il me semble donc qu'il devrait suffire de changer CV_64FC1 en CV_64FC2 dans la ligne
    CvMat *Ma = cvCreateMat(5, 5, CV_64FC1);
    pour rendre les éléments de la matrice Ma apte à recevoir et représenter les deux valeurs dénommées channels.


    J'ai l'impression que sous Python, deux channels sont représentés par un nombre complexe, mais il n'est pas dit qu'en C++ la représentation soit aussi sous forme de complexe. Je n'ai pas les moyens de vérifier car je ne sais pas faire tourner de programme C++. L'essentiel est d'obtenir une matrice en C++ qui comporte les mêmes valeurs qui sont sous Python dans les parties entières et imaginaires de complexes.





    Au début de la page déjà citée

    http://opencv.willowgarage.com/docum...tructures.html

    j'ai aussi lu:


    Template “traits” class for other OpenCV primitive data types

    template<typename _Tp> class DataType
    {
    etc

    (....)



    The template class DataType is descriptive class for OpenCV primitive data types and other types that comply with the following definition. A primitive OpenCV data type is one of unsigned char, bool (:math:`$\sim $`unsigned char), signed char, unsigned short, signed short, int, float, double or a tuple of values of one of these types, where all the values in the tuple have the same type.

    If you are familiar with OpenCV CvMat‘s type notation, CV_8U ... CV_32FC3, CV_64FC2 etc., then a primitive type can be defined as a type for which you can give a unique identifier in a form CV_<bit-depth>{U|S|F}C<number_of_channels>.

    (....)

    The class DataType is basically used to provide some description of such primitive data types without adding any fields or methods to the corresponding classes (and it is actually impossible to add anything to primitive C/C++ data types). This technique is known in C++ as class traits. It’s not DataType itself that is used, but its specialized versions, such as:



    template<> class DataType<uchar>
    { etc

    (....)

    The main purpose of the classes is to convert compile-time type information to OpenCV-compatible data type identifier, for example:

    // allocates 30x40 floating-point matrix
    Mat A(30, 40, DataType<float>::type);

    Mat B = Mat_<std::complex<double> >(3, 3);
    // the statement below will print 6, 2 /* i.e. depth == CV_64F, channels == 2 */
    cout << B.depth() << ", " << B.channels() << endl;
    that is, such traits are used to tell OpenCV which data type you are working with, even if such a type is not native to OpenCV (the matrix B intialization above compiles because OpenCV defines the proper specialized template class DataType<complex<_Tp> >).
    Les passages en rouge me suggèrent que la seule écriture CV_64FC2 ne suffira peut être pas et qu'il faudra peut être définir ce type dans le cadre d'une extension de la classe DataType. Mais rien n'est moins certain car je ne connais pas C++ et je suis frappé à chaque fois que je lis quelque chose sur C++ par son incompréhensibilité.




    Remarque au passage:

    pourquoi est-il écrit
    CvMat *Ma = cvCreateMat(5, 5, CV_64FC1);
    dans ton code
    alors que dans la page
    http://www.cs.iit.edu/~agam/cs512/le...00000000000000
    il y a
    CvMat* cvCreateMat(int rows, int cols, int type);

    C'est à dire la position de l'étoile, collée contre CvMat dans un cas et décollée dans l'autre

    Quelle est la fonction de cette étoile ?

  6. #6
    Membre du Club
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    65
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2009
    Messages : 65
    Points : 51
    Points
    51
    Par défaut
    Citation Envoyé par eyquem Voir le message
    Il me semble donc qu'il devrait suffire de changer CV_64FC1 en CV_64FC2 dans la ligne
    CvMat *Ma = cvCreateMat(5, 5, CV_64FC1);
    pour rendre les éléments de la matrice Ma apte à recevoir et représenter les deux valeurs dénommées channels.
    oui! c'est bien ça! CvMat contient des entiers/réels sur 2 dimensions! on utilise un CvMat à 2 canal pour les complexes!
    je donne un exemple fonctionnel ici
    il y a aussi l'exemple 'dft.c' (dans le dossier '%OPENCV_DIR%/samples/c') qui donne un exemple plus complet.

    @eyquem:
    l'étoile dans un code C/C++ est utilisé dans divers cas, votamment avec els pointeurs. tu peux le coller ou tu veux (y a pas de pb)

Discussions similaires

  1. Numpy et fft
    Par lafrite26 dans le forum Calcul scientifique
    Réponses: 6
    Dernier message: 28/06/2010, 20h29
  2. python 2.6.2 et Numpy 1.3.0
    Par billyrose dans le forum Déploiement/Installation
    Réponses: 2
    Dernier message: 21/05/2009, 18h55
  3. [python+numpy]Probleme tableaux numpy
    Par thibaultG dans le forum Calcul scientifique
    Réponses: 2
    Dernier message: 19/05/2008, 23h40
  4. [python+numpy] dictionnaire avec numpy
    Par thibaultG dans le forum Calcul scientifique
    Réponses: 5
    Dernier message: 16/05/2008, 11h35
  5. [NumPy] Fonction fft() issue de numpy/numarray
    Par Svart26 dans le forum Calcul scientifique
    Réponses: 9
    Dernier message: 26/06/2007, 23h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo