cv :: Mat的序列化产生奇怪的结果 [英] Serialization of cv::Mat giving strange result

查看:69
本文介绍了cv :: Mat的序列化产生奇怪的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试对openCV Mat进行序列化和反序列化,以便可以使用Boost将帧从客户端发送到服务器.我遇到的问题是,当我对图像进行反序列化时,它会以不同的颜色给出重复的重叠图像.我不确定为什么会这样.任何帮助将非常感激.很抱歉,我没有足够的徽章,因此无法发布图片.

用于自定义序列化cv :: Mat的头文件

  #ifndef cv__Mat_Serialization_serialization_h#define cv__Mat_Serialization_serialization_hBOOST_SERIALIZATION_SPLIT_FREE(cv :: Mat)命名空间提升{命名空间序列化{template< class Archive>无效的保存(存档&ar,const cv :: Mat& mat,const unsigned int version){size_t elementSize = mat.elemSize();size_t elementType = mat.type();ar<<mat.cols;ar<<垫行;ar<<elementSize;ar<<elementType;for(int y = 0; y< mat.rows * mat.cols *(elementSize); y ++){ar<<mat.data [y];}}template< class Archive>无效负载(存档&ar,cv :: Mat& mat,const unsigned int version){int cols = 0;int行= 0;size_t elementSize;size_t elementType;ar>>cols;ar>>行;ar>>elementSize;ar>>elementType;mat.create(rows,cols,static_cast< int>(elementType));for(int y = 0; y< mat.rows * mat.cols *(elementSize); y ++){ar>>mat.data [y];}}}}#万一 

主代码

  #include"serialization.h"使用命名空间std;使用命名空间cv;使用命名空间提升;垫框;void saveMat(Mat& m,字符串文件名);void loadMat(Mat& m,字符串文件名);int main(int argc,const char * argv []){//在此处插入代码...CvCapture *捕获= cvCaptureFromCAM(CV_CAP_ANY);//使用连接到系统的任何摄像机捕获cvNamedWindow("serialization",2);//创建窗口while(1){frame = cvQueryFrame(capture);saveMat(frame,"archive.bin");cv :: Mat frame2;loadMat(frame2,"archive.bin");IplImage tmp = frame2;cvShowImage("serialization",& tmp);}返回0;}void saveMat(Mat& m,字符串文件名){ofstream ofs(filename.c_str());存档:: binary_oarchive oa(ofs);oa<<m;}void loadMat(Mat& m,字符串文件名){ifstream ifs(filename.c_str());存档:: binary_iarchive ia(ifs);ia>>m;}在这里输入代码 

解决方案

我使用了您的确切代码,添加了 waitKey(...)来显示输出,没问题:

尽管如此,您应该在for循环中使用 size_t 而不是 int .您可以稍微减少变量的生命周期:

  while(1){{垫框= cvQueryFrame(capture);saveMat(frame,"archive.bin");}{cv :: Mat frame2;loadMat(frame2,"archive.bin");IplImage tmp = frame2;cvShowImage("serialization",& tmp);}if(waitKey(30)=='q')中断;} 

如果您遇到此问题,我想您的捕获源可能具有不同的图像表示形式,并且您可能想要执行类似的操作

  cvtColor(frame2,frame3,CV_BGR2RGB); 

I'm currently trying to serialize and deserialize an openCV Mat so that i can send the frame from a client to server using Boost. The problem i am having is that when i deserialise the image it gives duplicate overlapping images in different colours. I am not sure why this is happening. Any help would be much appreciated. I'm sorry I cannot post an image as i do not have enough badges.

header file for custom serialisation of cv::Mat

  #ifndef cv__Mat_Serialization_serialization_h
    #define cv__Mat_Serialization_serialization_h

    BOOST_SERIALIZATION_SPLIT_FREE(cv::Mat)
    namespace boost {
        namespace serialization {
            template<class Archive>
            void save(Archive & ar, const cv::Mat& mat, const unsigned int version) {
                size_t elementSize = mat.elemSize();
                size_t elementType = mat.type();

                ar << mat.cols;
                ar << mat.rows;
                ar << elementSize;
                ar << elementType;

                for(int y = 0; y < mat.rows*mat.cols*(elementSize); y++) {
                    ar << mat.data[y];
                }


            }
            template<class Archive>
            void load(Archive & ar, cv::Mat& mat, const unsigned int version) {
                int cols = 0;
                int rows = 0;
                size_t elementSize;
                size_t elementType;

                ar >> cols;
                ar >> rows;
                ar >> elementSize;
                ar >> elementType;

                mat.create(rows,cols,static_cast<int>(elementType));

                for(int y = 0; y < mat.rows*mat.cols*(elementSize); y++) {
                    ar >> mat.data[y];
                }
            }
        }
    }

    #endif

code for main

#include "serialization.h"

using namespace std;
using namespace cv;
using namespace boost;

Mat frame;

void saveMat(Mat& m, string filename);
void loadMat(Mat& m, string filename);

int main(int argc, const char * argv[]) {
    // insert code here...

    CvCapture* capture = cvCaptureFromCAM(CV_CAP_ANY);  //Capture using     any camera connected to your system
    cvNamedWindow("serialization", 2);    //Create window

    while(1) {
        frame = cvQueryFrame(capture);

        saveMat(frame, "archive.bin");
        cv::Mat frame2;
        loadMat(frame2, "archive.bin");
        IplImage tmp = frame2;

        cvShowImage("serialization", &tmp);
    }

    return 0;
}

void saveMat(Mat& m, string filename) {
    ofstream ofs(filename.c_str());
    archive::binary_oarchive oa(ofs);
    oa << m;
}

void loadMat(Mat& m, string filename) {
    ifstream ifs(filename.c_str());
    archive::binary_iarchive ia(ifs);
    ia >> m;
}
    enter code here

解决方案

I've used your exact code, adding a waitKey(...) to show the output, no problem:

You should use size_t instead of int in the for loops, though. And you could reduce lifetimes of variables a bit:

while(1) {
    {
        Mat frame = cvQueryFrame(capture); 

        saveMat(frame, "archive.bin");
    }

    {
        cv::Mat frame2;
        loadMat(frame2, "archive.bin");
        IplImage tmp = frame2;

        cvShowImage("serialization", &tmp);
    }

    if(waitKey(30) == 'q') break;
}

If you have this problem, I imagine your capture source may have a different image representation, and you may want to do something like

    cvtColor(frame2, frame3, CV_BGR2RGB);

etc.

这篇关于cv :: Mat的序列化产生奇怪的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆