OpenCV créer des Tapis de tableau d'octets
Dans ma dll C++ je suis la création de Tapis de tableau d'octets:
BYTE * ptrImageData; //Image data is in this array passed to this function
Mat newImg = Mat(nImageHeight, nImageWidth, CV_8UC3, ptrImageData);
L'image est créée avec une certaine nuance de gris ne pas l'original.
Est-ce la bonne façon de créer des Tapis de tableau d'octets?
Veuillez voir le code
ptrImageData est passé au C++ dll à partir de code C#.
Code C# pour transférer les données d'image
System.Drawing.Image srcImage //Has the image
MemoryStream ms = new MemoryStream();
Marshal.FreeHGlobal(ptrImageData);
srcImage.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] imgArray = ms.ToArray();
ms.Dispose();
int size1 = Marshal.SizeOf(imgArray[0]) * imgArray.Length;
IntPtr ptrImageData = Marshal.AllocHGlobal(size1);
Marshal.Copy(imgArray, 0, ptrImageData, imgArray.Length);
//Calling C++ dll function
ProcessImage(ptrImageData, srcImage.Width, srcImage.Height);
Marshal.FreeHGlobal(ptrImageData);
Je pense que votre code C++ a une erreur, Tapis de newImg(...), ou Mat* newImg = new Mat(..), votre écriture n'est pas style C++.
le code est correct. Dans le code ci-dessus,
Veuillez fournir des codes plus détaillés, par exemple comment afficher une image, quelle est la disposition de
veuillez voir le édités question avec le code
Pourquoi êtes-vous enregistrer votre image en JPEG lorsque vous voulez vraiment cru octets? Êtes-vous sûr de l'octet formats de
le code est correct. Dans le code ci-dessus,
newImg
est en cours d'initialisation à l'aide de la explicit
constructeur de la Mat
classe.Veuillez fournir des codes plus détaillés, par exemple comment afficher une image, quelle est la disposition de
ptrImageData
.veuillez voir le édités question avec le code
Pourquoi êtes-vous enregistrer votre image en JPEG lorsque vous voulez vraiment cru octets? Êtes-vous sûr de l'octet formats de
System.Drawing.Image
et cv::Mat
match? Pourquoi n'êtes-vous pas le formatage de l'exemple de code dans votre question?OriginalL'auteur user1858884 | 2012-11-28
Vous devez vous connecter pour publier un commentaire.
Le code C++ semble ok, dans ce que cela crée une matrice wrapper fourni des données d'image, en supposant que la mémoire tampon est dans le classique RGB8 format. Notez que ce constructeur ne pas copie de la mémoire tampon, de sorte que le tampon doit demeurer valide pour la durée de cette
Mat
instance (ou copier).Il semble que le problème réside dans Votre code C#. Je ne suis pas un développeur C#, mais je ferai de mon mieux pour vous aider. Vous créez un flux de mémoire et d'utiliser le JPEG codec pour écrire une version compressée de l'image dans la mémoire tampon comme si c'était un fichier. Mais c'est pas que le format de données
cv::Mat
attend, vous aurez essentiellement voir les ordures (données compressées interprété comme non compressé).Donné un
System.Image.Drawing.Image
exemple, vous pouvez créer un wrapperBitmap
objet directement (ou peut-être utiliseras
, puisque c'est une simple abattu). Ensuite, vous pouvez simplement utiliser leBitmap.LockBits()
méthode tog obtenir un pointeur vers l'image sous-jacente des données.et puis vous pouvez passer à la
rgbBuffer
à OpenCV.Je ne suis pas convaincu que la gestion de la mémoire dans le code d'origine est tout à fait correct, mais de toute façon la ci-dessus fonctionnera à condition que la portée de la mémoire tampon de la propriété est à l'intérieur de la verrouiller et déverrouiller les appels de méthode. Si les données de l'image est de survivre à ce bloc de code, vous devrez copier le tampon.
Être prudent avec vos formats de pixel de trop, vous devez vous assurer que le
Image/Bitmap
instance contient réellement RGB8 de données. OpenCV estcv::Mat
a divers drapeaux de sorte que vous pouvez travailler avec une variété de dans-mémoire de formats d'image. Mais notez que ce sont des pas le même que sur le disque (généralement compressés) formats tels que PNG, TIFF, et ainsi de suite.srcImage.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg)
d'appel pour utiliserImageFormat.Bmp
au lieu de la complexité de la conversion proposée iciOriginalL'auteur gavinb
Oui, c'est une façon de créer un Tapis à partir d'un tableau d'octets. Vous avez juste à faire attention à ce que votre tableau contient ce que vous pensez que cela fonctionne.
De sorte que vous obtenez une image en newImg? Quel est le format de pixel de l'origine des données?
Peut-être que vous avez mis le rouge et le bleu. La ligne suivante sera permuter les canaux:
OriginalL'auteur M Miller
Voici le lien pour docs: http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-mat
En général, vous devez prendre soin de deux choses l'une:
Je ne suis pas familier avec le C#, mais il me semble que vous avez communiqué des données juste après ProcessImage appel. Donc, si ProcessImage est asynchrone ou en quelque sorte les caches de votre matrice (c'est à dire la durée de vie de la matrice est plus que ProcessImage appel), vous devez être attentif à la gestion de la mémoire.
OriginalL'auteur Vlad