如果 Mat 对象不在 data 变量中,它会将其数据存储在哪里?

Posted

技术标签:

【中文标题】如果 Mat 对象不在 data 变量中,它会将其数据存储在哪里?【英文标题】:Where does a Mat object store its data if it's not in data variable? 【发布时间】:2020-11-12 15:19:27 【问题描述】:

我需要将图像数据从 Mat 对象 (OpenCV) 传输到 ZXing::ImageView 对象中的const unsigned char*;通常,我只是使用(假设对象被命名为“对象”)object.data,风险自负,如果转移出现问题,我会从那里开始。但是,在这种情况下,数据成员变量为空。这个 Mat 对象确实会生成带有 imshow 的图像,所以我不确定还能去哪里看。我已经阅读了文档,但我有限的经验和知识的缺乏使我无法以合理的速度或相关方向有效地阅读它。这是我的代码:

#include <opencv2/opencv.hpp>
#include <ZXing/ReadBarcode.h>
using namespace cv;

Mat applyThreshold(Mat gradient);
Mat erodeAnddilate(Mat threshold_applied);
void readBarCode(Mat dest);

int main() 
    std::string file = "C:\\Users\\these\\Desktop\\cropped.JPG";
    namedWindow("imageview", WINDOW_NORMAL);
    Mat src = imread(file, IMREAD_COLOR);
    Mat thresh_applied = applyThreshold(src);
    Mat dest = erodeAnddilate(thresh_applied);
    readBarCode(dest);
    imshow("imageview", dest);
    waitKey(0);
    
    return 0;


Mat applyThreshold(Mat gradient) 
    Mat dest, gray;
    cvtColor(gradient, gray, COLOR_BGR2GRAY);
    threshold(gray, dest, 0, 255, THRESH_BINARY + THRESH_OTSU);

    return dest;


Mat erodeAnddilate(Mat threshold_applied) 
    Mat dest;
    Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
    morphologyEx(threshold_applied, dest, MORPH_CLOSE, kernel, Point(-1, -1), 2);
    return dest;


void readBarCode(Mat dest) 
    ZXing::ImageView test(dest.data, dest.size().width, dest.size().height, ZXing::ImageFormat::None);
    ZXing::Result truth = ZXing::ReadBarcode(test);
    int momentoftruth = 0;

函数readBarCode() 是问题所在。并为其他地方可能糟糕的代码道歉,我还有很多东西要学。 :)

编辑:公认的解决方案是唯一官方给出的解决方案,但所有 cmets 共同帮助我意识到我在思考相关数据变量时的错误。我现在将数据变量视为指针,并将考虑浅拷贝和深拷贝作为潜在的解决方案。我对我的 Mat 对象的情况有了更好的理解,并认为我的问题得到了回答。谢谢大家。

【问题讨论】:

作为自己的练习,并可能吸引更高质量的答案,请考虑将其缩减为 minimal reproducible example。仅显示显示相同错误的最少代码集的做法可以帮助您更好地理解问题,并消除潜在回答者必须费力解决的许多问题。 “空”是什么意思? 如果第一个元素为零,那就是它应该的样子。 (我删除了我之前的评论,因为 VS 调试器可能将其解释为 C 风格的字符串。) main() 中的 dest 中的 data 变量是否为空?根据 CV 文档,通过复制创建 Mat 应该只复制指向数据的指针。 data 的值应该相同(并且都应该是指针,而不是字符串)。您的调试器看到它​​们是 uchar* 并假定它们是 c 风格的字符串。右键单击调试检查窗口中的变量并将其“格式”或“显示”或其他内容更改为“指针”?我目前没有安装 Visual Studio。 为了将来参考,您可以std::cout &lt;&lt; M &lt;&lt; '\n': 其中Mcv::Mat 以基于文本的良好格式显示矩阵的内容。 ***.com/questions/7970988/… 【参考方案1】:

尝试将您的 Mat 对象的引用传递给函数,或者如果您想复制数据以创建新图像,请明确使用 clone() 方法来获取图像的深层副本。

喜欢:

Mat applyThreshold(Mat& gradient) 
    Mat dest, gray;
    cvtColor(gradient, gray, COLOR_BGR2GRAY);
    threshold(gray, dest, 0, 255, THRESH_BINARY + THRESH_OTSU);

    return dest;

或:

// ...
Mat thresh_applied = applyThreshold(src.clone());
// ...

【讨论】:

感谢您的建议,但他们都没有解决我的问题。数据变量保持为空。 .data 是一个指向底层 n 维(如果是二维图像)数组的指针。你是什​​么意思它是空的?它通常必须有一个值,因为它是一个指针。例如,当您将图像分配给另一个图像或将图像作为参数传递时,不会复制基础数据。两个图像都指向相同的数据。例如,请参阅here。

以上是关于如果 Mat 对象不在 data 变量中,它会将其数据存储在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

对不在训练集中的新词使用 keras 分词器

在 Opencv 中将数据放入 Mat 对象中

matlAB如何保存变量

matlAB如何保存变量?

使用 opencv 中的文件存储将多个 Mat 变量写入 XML 文件

matlAB如何保存变量