std::vector<cv::Vec3b> 到 cv::Mat

Posted

技术标签:

【中文标题】std::vector<cv::Vec3b> 到 cv::Mat【英文标题】:std::vector<cv::Vec3b> to cv::Mat 【发布时间】:2019-03-27 15:12:55 【问题描述】:

将 cv::Vec3b 向量中包含 R、G 和 B 颜色值的向量转换为 cv::Mat 的最佳方法是什么?像素的位置无关紧要,我只想执行 cv::split 操作,然后将所有三个颜色级别都放到一个直方图中。

我试过这个,但它不起作用,因为拆分操作返回一个只有一个颜色平面的 cv::Mat:

cv::Mat GetOnlyColoredPixel(cv::Mat& Gray, cv::Mat& Col) 
    std::vector<cv::Vec3b> ColorStack;
    cv::Vec3b vec;
    int nPixel = 0;

    for (int y = 0; y < Gray.rows; y++) 
        for (int x = 0; x < Gray.cols; x++) 
            if (Gray.at<unsigned char>(y, x) == 255) 
                ColorStack.push_back(Col.at<cv::Vec3b>(y, x));
                nPixel++;
            
        
    

    return cv::Mat(1, nPixel, CV_8UC3, &ColorStack[0]);

奇怪的是,我真的应该只有黄色像素,但是在打印 MAT 对象时,我得到了所有可能的颜色。 Col.at&lt;cv::Vec3b&gt;(y, x) 返回正确的颜色,但按 RGB 顺序排列 - 我想,OpenCV 正在使用 BGR。

谢谢, 一月

【问题讨论】:

如果该向量不再更改并且在您使用垫子时(在拆分之前)没有超出范围,您可以直接使用内存:cv::Mat testMat = cv:Mat(height, width, CV_8UC3, ColorStack.data()); 然后您可以拆分 testMat或 .clone 它或任何你喜欢的。可能比您的方法少一份数据副本,但如果向量超出范围,则在您使用 testMat 完成所有操作之前会失败。 【参考方案1】:

好的,返回是错误的。此代码工作正常:

cv::Mat GetOnlyColoredPixel(cv::Mat& Gray, cv::Mat& Col) 
std::vector<cv::Vec3b> ColorStack;
cv::Vec3b vec, vec2;

cv::imwrite("C:\\HomeC\\Test.bmp", Col);

for (int y = 0; y < Gray.rows; y++) 
    for (int x = 0; x < Gray.cols; x++) 
        if (Gray.at<unsigned char>(y, x) == 255) 
            //ColorStack.push_back(Col.at<cv::Vec3b>(y, x));
            vec = Col.at<cv::Vec3b>(y, x);
            ColorStack.push_back(vec);
        
    


cv::Mat RetVal = cv::Mat(1, ColorStack.size(), CV_8UC3);
memcpy(RetVal.data, ColorStack.data(), ColorStack.size() * sizeof(cv::Vec3b));
return RetVal;

【讨论】:

【参考方案2】:
std::vector<cv::Vec3b> vec4cv::Vec3b(0,0,0), cv::Vec3b(0,0,0);
cv::Mat mat4(vec4.size(), 1, CV_8UC3, vec4.data());
std::cout << mat4 << std::endl;

cv::Vec3b的类型是CV_8UC3,可以从https://udayawijenayake.com/2021/06/07/opencv-data-types/查看

【讨论】:

以上是关于std::vector<cv::Vec3b> 到 cv::Mat的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV 无效操作数错误

在 OpenCV 中应用蒙版

从 std::vector<std::vector<float>> 转换为 float**

如何将 std::vector<std::vector<double>> 转换为 torch::Tensor?

C++随机选择std::vector的非空元素<std::vector>>

如何将 std::vector<std::vector<double>> 转换为 Rcpp::Dataframe 或 Rcpp::NumericMatrix