Opencv 构建cv::Mat的不同方法有哪些?

Opencv 构建cv::Mat的不同方法有哪些?,opencv,Opencv,OpenCV版本3.2.0 我正在阅读布拉德斯基的作品,并试图制作不同的cv::Mat构造函数-单通道。 有人能告诉我为什么施工人员不工作吗 float data1[6] = {1,2,3,4,5,6}; float data2[6] = {10,20,30,40,50,60}; float data3[6] = {100,200,300,400,500,600}; cv::Mat mat1(3,4,CV_32FC1); //OK cv::Mat mat2(3,4,CV_32FC1,cv::S

OpenCV版本3.2.0

我正在阅读布拉德斯基的作品,并试图制作不同的cv::Mat构造函数-单通道。 有人能告诉我为什么施工人员不工作吗

float data1[6] = {1,2,3,4,5,6};
float data2[6] = {10,20,30,40,50,60};
float data3[6] = {100,200,300,400,500,600};

cv::Mat mat1(3,4,CV_32FC1); //OK
cv::Mat mat2(3,4,CV_32FC1,cv::Scalar(33.3)); //OK
cv::Mat mat3(3,4,CV_32FC1,data1,sizeof(float)); //OK
cv::Mat mat4(cv::Size(3,4),CV_32FC1); //OK
cv::Mat mat5(cv::Size(3,4),CV_32FC1,cv::Scalar(66.6)); //OK
cv::Mat mat6(cv::Size(3,4),CV_32FC1,data2,sizeof(float)); //OK
int sz[] = {8, 8, 8};
cv::Mat bigCube1(3, sz, CV_32FC1); // OK
cv::Mat bigCube2(3, sz, CV_32FC1, cv::Scalar::all(99)); // OK 
cv::Mat bigCube3(3, sz, CV_32FC1, data3, 4); // Not OK, How to initialise a 3D from data?
std::cout << mat1 << std::endl << mat2 << std::endl << mat3 << std::endl << mat4 << std::endl << mat5 << std::endl << mat6 << std::endl; // OK                                                                   
std::cout << bigCube1.at<float>(10,10,10)  << std::endl << bigCube2.at<float>(10,10,10) << std::endl; // OK

cv::Mat img_rgb = cv::imread("lena.jpg", CV_LOAD_IMAGE_COLOR);
std::vector<cv::Range> ranges(3, cv::Range(2,3));

cv::Mat roiRange( img_rgb, cv::Range(100, 300), cv::Range(0, 512)); //OK
cv::Mat roiRect( img_rgb, cv::Rect(0,100,512,200)); // OK
cv::Mat roiRangeMultiple( bigCube1, ranges); // OK

cv::namedWindow("range", CV_WINDOW_AUTOSIZE);
imshow("range", roiRange);  // OK
cv::namedWindow("rect", CV_WINDOW_AUTOSIZE);
imshow("rect", roiRect); // OK
std::cout << roiRangeMultiple.at<float>(0,1,1); // Not OK. Expecting a float value as answer
cv::waitKey(0);
然后lena.jpg对应的答案是Range和Rect的裁剪版本。但是我不知道如何使用这些范围。

多个问题

cv::Mat mat3(3,4,CV_32FC1,data1,sizeof(float));
这将在调试模式下崩溃,失败。即使文档中没有,步长也必须至少等于行的长度(即不允许重叠)

此场景的正确代码如下所示

float data1[12] = { 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 };
cv::Mat mat3(3, 4, CV_32FC1, data1, 4 * sizeof(float));

与前一案例类似的情况。还要注意,这会产生一个不同形状的数组——前面的是3行4列,这个有4行3列(请参阅)


这里的问题是最后一个参数。从

步骤-多维数组中ndims-1步骤的数组(最后一步始终设置为元素大小)。如果未指定,则假定矩阵是连续的

  • 您没有将步骤数组作为最后一个参数传递(仅传递一个整数)
  • 你没有传递足够的数据
  • 这两行会再次重叠
一种方法是

float data3[8 * 8 * 8];
// Populate the data with sequence 0..511
std::iota(std::begin(data3), std::end(data3), 0.0f);

int sz[] = { 8, 8, 8 };
size_t steps[] = { 8 * 8 * sizeof(float), 8 * sizeof(float) };
cv::Mat bigCube3(3, sz, CV_32FC1, data3, steps);

更改后,您拥有正确的类型。但是请注意,您从不初始化
bigCube1
。结果很可能是0.0f,打印为
0
。您可以自己尝试,只需执行多个问题

cv::Mat mat3(3,4,CV_32FC1,data1,sizeof(float));
这将在调试模式下崩溃,失败。即使文档中没有,步长也必须至少等于行的长度(即不允许重叠)

此场景的正确代码如下所示

float data1[12] = { 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 };
cv::Mat mat3(3, 4, CV_32FC1, data1, 4 * sizeof(float));

与前一案例类似的情况。还要注意,这会产生一个不同形状的数组——前面的是3行4列,这个有4行3列(请参阅)


这里的问题是最后一个参数。从

步骤-多维数组中ndims-1步骤的数组(最后一步始终设置为元素大小)。如果未指定,则假定矩阵是连续的

  • 您没有将步骤数组作为最后一个参数传递(仅传递一个整数)
  • 你没有传递足够的数据
  • 这两行会再次重叠
一种方法是

float data3[8 * 8 * 8];
// Populate the data with sequence 0..511
std::iota(std::begin(data3), std::end(data3), 0.0f);

int sz[] = { 8, 8, 8 };
size_t steps[] = { 8 * 8 * sizeof(float), 8 * sizeof(float) };
cv::Mat bigCube3(3, sz, CV_32FC1, data3, steps);



更改后,您拥有正确的类型。但是请注意,您从不初始化
bigCube1
。结果很可能是0.0f,打印为
0
。您可以自己尝试,只需执行
std::cout
mat3
mat6
就行了。至少OpenCV 3.x步长至少等于一行的长度(即不允许重叠)。@DanMašek它可以工作。结果就在答案里。sizeof(float)在源数组中按一个元素步进。它不必是至少自OpenCV 2.2以来一直存在的sizeof(row)。当然,由于它是一个
CV_DbgAssert
,它只会在调试模式下启动,而在发布模式下它会“工作”。然而,在调试模式下崩溃和烧坏的东西并不是我所说的工作。bigcube1似乎是在我的计算机上编译的。“不好”是什么意思?编译?跑?给出错误?哪个错误?还要注意,
操作员
mat3
mat6
使用的格式化功能似乎不正常。至少OpenCV 3.x步长至少等于一行的长度(即不允许重叠)。@DanMašek它可以工作。结果就在答案里。sizeof(float)在源数组中按一个元素步进。它不必是至少自OpenCV 2.2以来一直存在的sizeof(row)。当然,由于它是一个
CV_DbgAssert
,它只会在调试模式下启动,而在发布模式下它会“工作”。然而,在调试模式下崩溃和烧坏的东西并不是我所说的工作。bigcube1似乎是在我的计算机上编译的。“不好”是什么意思?编译?跑?给出错误?哪个错误?还要注意,
operatorI使用的格式化函数将通过它。看起来我需要一个完整的OpenCV重新编译和调试,对吗?是的,你需要一个OpenCV的调试版本。我想在这种情况下我不需要CMAKE_build_类型的调试。在编译过程中只需将_调试传递给源文件就可以了,对吗?我的意思是,我不想调试opencv,只想激活断言。但是,我在cmake文件中找不到任何相应的调试选项。。你能告诉我你是怎么做到的吗?我只是有一个OpenCV的调试版本,我用它来调试我的代码(因为我使用的是MSVC++,这是一种必要的)。基本上就像你在
CMAKE\u BUILD\u TYPE
设置为
Debug
时得到的一样。只是一个小提示,因为你的评论有点误导。CV_DbgAssert()既不需要opencv中的调试符号,也不需要应用程序代码。在编译应用程序代码的过程中通过_DEBUG宏就足够了。看起来我需要一个完整的OpenCV重新编译和调试,对吗?是的,你需要一个OpenCV的调试版本。我想在这种情况下我不需要CMAKE_build_类型的调试。在编译过程中只需将_调试传递给源文件就可以了,对吗?我的意思是,我不想调试opencv,只想激活断言。但是,我在cmake文件中找不到任何相应的调试选项。。你能告诉我你是怎么做到的吗?我只是有一个OpenCV的调试版本,我用它来调试我的代码(因为我使用的是MSVC++,这是一种必要的)。基本上就像你在
CMAKE\u BUILD\u TYPE
设置为
Debug
时得到的一样。只是一个小提示,因为你的评论有点误导。CV_DbgAssert()既不需要opencv中的调试符号,也不需要应用程序代码。它足以通过_DEB
for (auto const& v : cv::Mat1b(bigCube2)) {
    std::cout << uint(v) << " ";
}
std::cout << "\n";
cv::Mat bigCube3(3, sz, CV_32FC1, data3, 4);
cv::Mat::Mat(int ndims,
    const int *   sizes,
    int type,
    void * data,
    const size_t * steps = 0 
    )
float data3[8 * 8 * 8];
// Populate the data with sequence 0..511
std::iota(std::begin(data3), std::end(data3), 0.0f);

int sz[] = { 8, 8, 8 };
size_t steps[] = { 8 * 8 * sizeof(float), 8 * sizeof(float) };
cv::Mat bigCube3(3, sz, CV_32FC1, data3, steps);
cv::Mat bigCube1(3, sz, CV_8UC1);
// ...
std::cout << roiRangeMultiple.at<float>(0,1,1); // Not OK. Expecting a float value as answer
std::cout << roiRangeMultiple.at<unsigned char>(0,0,0);