如何将单个图像从图像矢量复制到临时 cv::Mat?
Posted
技术标签:
【中文标题】如何将单个图像从图像矢量复制到临时 cv::Mat?【英文标题】:How to copy single image from vector of images to a temporary cv::Mat? 【发布时间】:2013-06-04 12:47:10 【问题描述】:我调用函数 rgbTOgray 并尝试使用 for 循环将“图像矢量”(这是彩色图像的矢量)中的每个图像复制到临时 cv::Mat。并且,使用 cvtColor 将其转换为灰度。代码如下:
std::vector<cv::Mat> rgbTOgray(std::vector<cv::Mat>& rgb_image)
cv::Mat temp_gray, temp_rgb;
std::vector<cv::Mat> gray_image;
std::vector<cv::Mat>::iterator itr;
for ( itr = rgb_image.begin() ; itr < rgb_image.end() ; itr++)
temp_rgb = *itr;
cvtColor(temp_rgb, temp_gray, CV_RGB2GRAY);
gray_image.push_back(temp_gray);
return gray_image;
编辑:我正在返回灰度图像“gray_image”的矢量。但这似乎不起作用。
EDIT_2: OpenCV 错误:cvtColor 中的断言失败 (scn == 3 || scn == 4)
有人可以帮帮我吗?我是新手,正在学习所有这些东西。 谢谢!
【问题讨论】:
什么不起作用?您能否提供错误消息或预期/实际输出? @JBL 请检查 EDIT_2 是否有错误 这可能会有所帮助:***.com/questions/6884660/… @JBL 是行:“ temp_rgb = *itr ”对吗?我也试过 *itr.copyTo(temp_rgb) 不起作用... 【参考方案1】:一个问题是您忘记了 cv::Mat
是使用“副本”进行引用计数的,而不是真正复制任何内容,只是一个指针。push_back(temp_grey)
不断将相同的图像推送到您的阵列中。
您应该在循环内声明 cv::Mat temp_gray
以确保您获得每个元素的新副本。
另外,检查“rgb”图像的通道数 (temp_rgb.channels()
)。断言基本上说它们不是 3/4 通道。
【讨论】:
如何查看频道数? @user2151446 谢谢!!通道数确实是1。有没有办法将单通道图像转换为3通道图像? @AdiShavit 也感谢你!!通道数确实是 1。有没有办法将单通道图像转换为 3 通道图像?我认为这些是单通道 rgb 图像....我需要将它们转换为灰度图像才能让我的其余代码完美运行.... 如果图像只有 1 个通道,则表示它不是 RGB 图像(据我所知)。你确定这些图像还没有灰度吗?使您的函数对灰色和 rgb 图像有效的一种方法是仅使用单个通道复制图像。 我发现我可以直接将图像读取为灰度:imread(path, CV_LOAD_IMAGE_GRAYSCALE)) 现在不需要上面的函数了!! :D 谢谢大家!!!【参考方案2】:您不是将灰度图像存储在矢量gray_image
中,而是在cv::Mat
标头中存储指向首先由temp_gray
分配的单个内存数据块的指针。您必须克隆这些数据以不覆盖您的图像:
gray_image.push_back(temp_gray.clone());
顺便说一句,我会在你的循环之前添加gray_image.reserve(rgb_image.size());
。
【讨论】:
这行:'temp_rgb = *itr' 正确吗?我也试过 *itr.copyTo(temp_rgb) 不起作用... 没关系,但您实际上并不需要它。你可以写 cvtColor(*itr, temp_gray, CV_RGB2GRAY);【参考方案3】:我不知道确切原因(我也是一个学习者),但在我的情况下,当您将临时图像推回只是灰度转换时,它仅适用于 .clone()
。
不管怎样,你代码中的迭代器行是正确的。
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
std::vector<cv::Mat> rgb2gray(std::vector<cv::Mat>& rgb_image)
cv::Mat temp_gray;
std::vector<cv::Mat> gray_image;
std::vector<cv::Mat>::iterator itr;
gray_image.reserve(rgb_image.size());
for ( itr = rgb_image.begin() ; itr < rgb_image.end() ; itr++)
cvtColor(*itr, temp_gray, CV_RGB2GRAY);
gray_image.push_back(temp_gray.clone());
return gray_image;
int main(int /*argc*/, char** /*argv*/)
Mat imgA, imgB;
imgA = imread("test1.jpg");
imgB = imread("test2.jpg");
vector<Mat> input;
input.push_back(imgA);
input.push_back(imgB);
vector<Mat> output;
output = rgb2gray(input);
stringstream ss;
for(size_t i = 0; i<input.size(); i++)
ss.str(""); ss << "in" << i;
imshow( ss.str(), input[i] );
ss.str(""); ss << "out" << i;
imshow( ss.str(), output[i] );
while( true )
char c = (char)waitKey(10);
if( c == 27 )
break;
return 0;
【讨论】:
我发现我可以直接读取灰度图像:imread(path, CV_LOAD_IMAGE_GRAYSCALE)) 谢谢!以上是关于如何将单个图像从图像矢量复制到临时 cv::Mat?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 cv::mat 标头和数据部分转换为单个 qbytearray?
如何将多个(超过 4 个)`CV::Mat` 图像`Size(M, N), CV_8UC1` 加入到一个 RGBA 图像中?