将Caffe caffe :: Datum转换为OpenCV cv :: Mat in C ++

时间:2016-09-29 19:10:14

标签: c++ opencv image-processing caffe

我正在做一些调试,所以我要转储图像文件来查看预测和转换。

我可以从cv :: Mat创建一个caffe :: Datum:

cv::Mat matrix;
// ... initialize matrix
caffe::Datum datum;
caffe::CVMatToDatum(matrix, &datum)

但如何从caffe :: Datum创建一个cv :: Mat?以下代码给出致命异常“Datum not encoded”:

caffe::Datum datum;
// ... initialize datum
cv::Mat matrix;
matrix = DecodeDatumToCVMat(datum, true);

2 个答案:

答案 0 :(得分:2)

您可以使用以下功能。

cv::Mat DatumToCVMat(const Datum& datum){
int datum_channels = datum.channels();
int datum_height = datum.height();
int datum_width = datum.width();

string strData = datum.data();
cv::Mat cv_img;
if (strData.size() != 0)
{
    cv_img.create(datum_height, datum_width, CV_8UC(datum_channels));
    const string& data = datum.data();
    std::vector<char> vec_data(data.c_str(), data.c_str() + data.size());

    for (int h = 0; h < datum_height; ++h) {
        uchar* ptr = cv_img.ptr<uchar>(h);
        int img_index = 0;
        for (int w = 0; w < datum_width; ++w) {
            for (int c = 0; c < datum_channels; ++c) {
                int datum_index = (c * datum_height + h) * datum_width + w;
                ptr[img_index++] = static_cast<uchar>(vec_data[datum_index]);
            }
        }
    }
}
else
{
    cv_img.create(datum_height, datum_width, CV_32FC(datum_channels));
    for (int h = 0; h < datum_height; ++h) {
        float* ptr = cv_img.ptr<float>(h);
        int img_index = 0;
        for (int w = 0; w < datum_width; ++w) {
            for (int c = 0; c < datum_channels; ++c) {
                ptr[img_index++] = static_cast<float>(datum.float_data(img_index));
            }
        }
    }
}
return cv_img;

}

所有代码: http://lab.deepaivision.com/2017/06/opencv-mat-caffe-datum-datum-mat.html

答案 1 :(得分:0)

除了@ ttagu99的答案外,在float部分中还有一个小错误: 该行:

ptr[img_index++] = static_cast<float>(datum.float_data(img_index));

实际上应该是:

int datum_index = (c * datum_height + h) * datum_width + w;
ptr[img_index++] = static_cast<float>(datum->float_data(datum_index));

这确定了将数据写入矩阵的顺序。否则,您只会看到彩色线条。