2012-12-04 2 views
5

je besoin de mettre en oeuvre une fonction qui reçoit une chaîne contenant les octets d'une image (reçu via une connexion de socket boost) et convertit la page dans un OpenCV cv: : Mat.Autre une chaîne d'octets à cv :: mat

Je connais également la largeur et la hauteur de l'image et sa taille en octets. Ma fonction ressemble à ceci:

void createImageFromBytes(const std::string& name, std::pair<int,int> dimensions, const std::string& data) 
{ 
    int width,height; 
    width = dimensions.first; 
    height = dimensions.second; 
    //convert data to cv::Mat image 

    std::string filepng = DATA_PATH"/" + name +".png"; 
    imwrite(filepng, image); 
} 

Quelle est la meilleure méthode pour cela? Est-ce que OpenCV a un constructeur pour Mat à partir d'une chaîne?

Répondre

9

OpenCV Mat a un constructeur de vector<byte>, mais ce n'est pas si intuitif. Vous devez convertir la chaîne au vecteur de cette façon première:

std::vector<byte> vectordata(data.begin(),data.end()); 

Ensuite, vous pouvez créer un cv :: Mat à partir du vecteur:

cv::Mat data_mat(vectordata,true); 

Vous devez également décoder l'image (vérifier la documentation pour quels types sont autorisés, png, jpg, selon la version OpenCV)

cv::Mat image(cv::imdecode(data_mat,1)); //put 0 if you want greyscale 

maintenant, vous pouvez vérifier si la taille résultante de l'image est le même que celui que vous avez envoyé:

cout<<"Height: " << image.rows <<" Width: "<<image.cols<<endl; 
1

Si les données de la chaîne est pixels bruts (plutôt que d'un Jpeg/png etc), vous pouvez créer le cv :: tapis directement

// assuming an RGB image in bytes    
cv::Mat mat(height,width,CV_8UC3,string.data()); 
+4

Sans petite bête, mais ne sont pas la hauteur et les rangées la même chose? – trianta2

+0

Je reçois des erreurs de compilation se plaignant qu'il n'y a pas de constructeur correspondant à cette utilisation de cv :: Mat. Peut-être mises à jour à opencv depuis votre message ont brisé votre solution? –

0

Voici ma solution améliorée de Jav_Rock, le problème est ce n'est pas clair pour utiliser vecteur (type octet est pas défini dans C++, je ne l'ai pas trouvé que), au lieu de cela, utiliser vecteur, voici un exemple de code

int func(char * pfile){ 
string strfile = pfile; 
std::vector<unsigned char> vectordata(strfile.begin(),strfile.end()); 
Mat data_mat(vectordata, true); 
Mat graySacleFrame = imdecode(data_mat, 0); //PGM image 
... 
}