Comment transférer la propriété des données de pixels à cv :: Mat

Je crée un cv :: Mat en passant avec les données de pixels allouées de manière externe.

cv::Mat myMasortingx(vImageResult.height, vImageResult.width, CV_8UC1, vImageResult.data); 

Je voudrais que cv :: Mat devienne propriétaire des octets (c.-à-d. Crée un refCount et libère les octets quand il atteint zéro). Cependant la documentation dit

Les constructeurs de masortingce qui prennent des données et des parameters d’étape n’allouent pas de données de masortingce. Au lieu de cela, ils initialisent simplement l’en-tête de la masortingce qui pointe vers les données spécifiées, ce qui signifie qu’aucune donnée n’est copiée. Cette opération est très efficace et peut être utilisée pour traiter des données externes à l’aide des fonctions OpenCV. Les données externes ne sont pas automatiquement désallouées, vous devez donc vous en occuper.

  • Si je vImageResult.data immédiatement le vImageResult.data sous-jacent, je vImageResult.data un blocage des access, quelque part sur la ligne.
  • Si je ne libère pas le vImageResult.data sous-jacent, les données vImageResult.data .

Y at-il un moyen de passer la propriété?

Tu ne peux pas.

cv :: Mat ne sait pas comment vous avez alloué la mémoire (malloc, new, etc.) et ne sait donc pas comment le libérer.

Si vous allouez les données vous-même, vous pouvez toujours appeler cv::Mat::create(...) pour allouer la mémoire dont vous avez besoin, puis passer le pointeur myMasortingx.data à la fonction que vous utilisez pour charger les données.

Si vous vous référez à la mémoire préallouée qui vous est fournie via un stream de capture vidéo ou une bibliothèque externe, vous n’avez pas de chance.

La solution d’Andreas fonctionnera, mais peut être lente si elle est utilisée fréquemment.

Un compromis peut être d’envelopper cv::Mat dans votre propre type:

 struct MyMat { cv::Mat mat; MyMat(int width, int height, int format, char *data) : mat(height, width, format, data){} ~MyMat() { delete [] mat.data; } }; 

Remarque: il était intentionnel de ne pas essayer de sous-classe cv :: Mat. Il n’a pas de destructeur virtuel.

Une option consiste à copier les données dans une nouvelle masortingce à l’aide de Mat::clone() , qui effectue une copie complète des données. La nouvelle masortingce sera alors propriétaire des données clonées.

Par exemple:

 // create temporary masortingx that holds the external/old data cv::Mat tmp(vImageResult.height, vImageResult.width, CV_8UC1, vImageResult.data); cv::Mat myMasortingx = tmp.clone(); // myMasortingx now has ownership of a clone of the data.