Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ cv::Mat到std::字符串序列化和反序列化导致错误结果_C++_Image_Opencv - Fatal编程技术网

C++ cv::Mat到std::字符串序列化和反序列化导致错误结果

C++ cv::Mat到std::字符串序列化和反序列化导致错误结果,c++,image,opencv,C++,Image,Opencv,我尝试下面的代码来序列化和反序列化cv::Mat对象。它只是将所有uchar记录到一个ostringstream中,然后将其转换为字符串进行序列化。然后我使用istringstream反序列化这个字符串,并将所有UChar保存到Mat对象中。Mat类型CV_8UC3是合法的,我使用应答中的函数检查了它。8UC3是作为参数给出的测试垫的通道。我知道这可能是一种蹩脚的连载方式,所以我愿意接受更好的想法。不管怎么说,我只得到了画面中25%的部分。其余的都不见了。我中间有一种奇怪的颜色失真。输出和输入图

我尝试下面的代码来序列化和反序列化cv::Mat对象。它只是将所有uchar记录到一个ostringstream中,然后将其转换为字符串进行序列化。然后我使用istringstream反序列化这个字符串,并将所有UChar保存到Mat对象中。Mat类型CV_8UC3是合法的,我使用应答中的函数检查了它。8UC3是作为参数给出的测试垫的通道。我知道这可能是一种蹩脚的连载方式,所以我愿意接受更好的想法。不管怎么说,我只得到了画面中25%的部分。其余的都不见了。我中间有一种奇怪的颜色失真。输出和输入图像位于代码下方。如果你需要更多的细节,请随时询问

void dbop::serializeMat(cv::Mat operand) {

std::ostringstream srlzstrstream;
srlzstrstream << operand.rows << " " << operand.cols << " " ;
for(int i = 0; i < operand.rows; i++)
    for (int j = 0; j < operand.cols; j++)
        srlzstrstream << operand.at<uchar>(i, j);

std::string srlzdstr = srlzstrstream.str();

uchar uchoper;
int row, col;
std::istringstream desrlzstrstream(srlzdstr);

desrlzstrstream >> row;
desrlzstrstream >> col;
cv::Mat matoper(row, col, CV_8UC3);

for (int i = 0; i < row; i++) {
    for (int j = 0; j < col; j++) {
        desrlzstrstream>> uchoper;
        matoper.at<uchar>(i, j) = uchoper;
    }
}

return;
}
编辑 rafix07遵循您的建议后,我找到了一种每像素3字节的替代方法。现在我得到了完整的图片,但是颜色失真或其他任何它被称为现在比以往更糟糕。输出图像顶部10%的ish值很好,但低于此值则会陷入地狱。请参见下面的代码图

void dbop::serializeMat(cv::Mat operand) {
std::ostringstream srlzstrstream;
cv::uint8_t* pixelPtr = (uint8_t*)operand.data;
int cn = operand.channels();
cv::Scalar_<uint8_t> bgrPixel;

srlzstrstream << operand.rows << " " << operand.cols << " ";
for (int i = 0; i < operand.rows; i++) {
    for (int j = 0; j < operand.cols; j++) {
        bgrPixel.val[0] = pixelPtr[i * operand.cols * cn + j * cn + 0]; // B
        bgrPixel.val[1] = pixelPtr[i * operand.cols * cn + j * cn + 1]; // G
        bgrPixel.val[2] = pixelPtr[i * operand.cols * cn + j * cn + 2]; // R
        srlzstrstream << bgrPixel.val[0] << bgrPixel.val[1] << bgrPixel.val[2];
    }
}
std::string srlzdstr = srlzstrstream.str();
uchar uchoper1, uchoper2, uchoper3;
int row, col;
std::istringstream desrlzstrstream(srlzdstr);

desrlzstrstream >> row;
desrlzstrstream >> col;
cv::Mat matoper(row, col, CV_8UC3);

for (int i = 0; i < row; i++) {
    cv::Vec3b* ptr = matoper.ptr<cv::Vec3b>(i);
    for (int j = 0; j < col; j++) {
        desrlzstrstream >> uchoper1;
        desrlzstrstream >> uchoper2;
        desrlzstrstream >> uchoper3;
        ptr[j] = cv::Vec3b(uchoper1, uchoper2, uchoper3);
    }
}
return;
}
假设你有:

uchar ch = 10;
ostringstream os;
os << ch;
因为ostringstream在上述情况下将存储在无符号字符中的所有值视为字符,所以10表示换行符,并且此换行符被放入流中,而不是其数值。您必须以至少16位的精度写入/读取整数。另一个问题是,当推送到流中时,必须在值之间添加空格

因此,第一个更新是:

srlzstrstream << (int)bgrPixel.val[0] << " " << (int)bgrPixel.val[1] << " " << (int)bgrPixel.val[2] << " ";

您只从输入的彩色图像中写入一个字节?您的输出是CV_8UC3,3个通道。它彼此不匹配。@rafix07您是对的,在您的建议之后,我找到了一种更好的表示每像素3字节的方法,但现在问题不同了。检查编辑。是的,这正好解决了问题。我原以为把它们放到其他地方会导致数据丢失或其他什么,但我想我错了谢谢你,伙计!
[
]
srlzstrstream << (int)bgrPixel.val[0] << " " << (int)bgrPixel.val[1] << " " << (int)bgrPixel.val[2] << " ";
uint16_t uchoper1, uchoper2, uchoper3;