2017-03-16 1 views
1

Pour un peu de contexte, je fais beaucoup de filtrage d'image, en utilisant un tas de filtres complexes. Je génère les parties réelle et imaginaire des filtres séparément (c'est plus efficace de cette façon), et les stocke dans deux tableaux séparés. J'ai suivi this guide sur comment faire dft dans opencv.Dans OpenCV, existe-t-il un moyen de combiner/séparer les canaux d'image plus efficacement que cv :: merge et cv :: split?

Fondamentalement, je dois

    boucle
  1. par mes filtres
  2. fusion d'appel de combiner les parties réelles et imaginaires
  3. effectuer une DFT
  4. appel divisé pour séparer réelle et imaginaire à nouveau
  5. calculer l'ampleur de la réponse

Je fais cela, et c'est assez lent. J'ai d'abord pensé que j'avais besoin d'une bibliothèque FFT plus rapide, mais en se basant sur le profileur de Visual Studio, il s'avère que cv :: split() et cv :: merge() prennent plus de temps que la DFT réelle. En fait, la plupart du temps d'exécution est consacré à ces deux fonctions. L'ensemble de la séparation/fusion semble un peu redondant pour moi, et le fait que ce sont les fonctions qui prennent le plus de temps est assez ennuyeux. Y a-t-il un moyen plus rapide de faire ce que j'essaie de faire?

Répondre

1

Les matrices OpenCV sont stockées au format entrelacé. Cela signifie que pour une image à deux canaux avec les canaux A et B, une matrice 4x1 serait stockée dans l'ordre ABABABAB. Si vous avez deux plans différents, vous avez AAAA et BBBB.

Il est probablement plus difficile de convaincre la DFT de fonctionner sur une entrée non entrelacée. Cependant, peut-être que vous êtes en mesure de stocker vos filtres en tant que matrice à deux canaux en premier lieu?

Pour calculer la magnitude à partir des deux canaux, vous pouvez parcourir tous les éléments et appeler cv :: norm sur eux ou faire le calcul vous-même. Vous pouvez accélérer encore plus en utilisant SSE et/ou TBB.

Alors au moins, vous enregistrez l'une des conversions.

+0

Merci pour les suggestions. En ce qui concerne les filtres en tant que matrice à deux canaux, l'obstacle principal que j'ai rencontré est que j'ai besoin de faire une multiplication complexe par élément pour appliquer les filtres. Une fois que vous avez fusionné, OpenCV n'a aucune idée que les nombres sont complexes, il est traité comme une image à deux canaux. Donc je devrais les séparer pour effectuer la multiplication efficacement. – user3765410

+0

Eh bien, vous pouvez aussi faire un chemin totalement différent en utilisant des matrices de type 'cv :: Complex', dont les données peuvent être directement introduites dans la méthode dct de libfftw castée en' fftw_complex'. – ypnos