我正在尝试在opencv中索引3通道图像。
当我读入图像文件时,此代码可以正常工作
int Blue = LeftCol.at<cv::Vec3b>(v,u)[0];
int Green = LeftCol.at<cv::Vec3b>(v,u)[1];
int Red = LeftCol.at<cv::Vec3b>(v,u)[2];
但是当我使用网络摄像头输入时它会崩溃。网络摄像头有3个频道,u,v
从0,0
开始。
我不知道为什么它不起作用。
我已尝试过Vec3b
,Vec3i
,Vec3s
,Vec3f
,Vec3d
我迷路了......为什么我不能索引这个网络摄像头图像?
对,所以经过几个小时后,这就是我要去的地方......这是该计划的概要。我在函数中遇到了上面提到的问题。所以我回到了基础,尝试在函数之前查看矩阵......
void main (int argc, char** argv) {
Mat LeftCol;
while (1==1) {
if (ProgramMode == "Files") {
//read in the colour images
LeftCol = imread(ColImLeft.c_str(),1);
RightCol = imread(ColImRight.c_str(),1);
} else if (ProgramMode == "Camera") {
VideoCapture CapLeft, CapRight;
CapLeft.open(1);
CapRight.open(2);
CapLeft >> LeftCol;
CapRight >> RightCol;
//THIS WORKS, THIS PIXEL VALUES ARE DISPLAYED
cout << "uchar" << endl;
for (int x=0;x<10;x++) {
for (int y=0;y<10;y++) {
int pixel = LeftCol.at<cv::Vec3b>(x,y)[0];
cout << pixel;
}
cout << endl;
}
} //end if
///////ADDED THIS BIT ////////
cout << "channels = " << LeftCol.channels() << endl;
//^^This bit works, output shows "channels = 3"
//vv This bit doesn't work.... so there's a problem with LeftCol.
//I wonder if reading the data like CapLeft >> LeftCol; is changing something
imshow("Test",LeftCol);
///////ADDED THIS BIT ////////
//THIS DOES NOT WORK WHEN USING THE CAMERA INPUT, PROGRAM CRASHES
cout << "uchar" << endl;
for (int x=0;x<10;x++) {
for (int y=0;y<10;y++) {
int pixel = LeftCol.at<cv::Vec3b>(x,y)[0];
cout << pixel;
} //end for
cout << endl;
} //end for
} //end while
} //end main
对,我有它的工作,但它并不理想。我正在创建一个临时Mat
来读取文件然后克隆它们。
Mat TempLeft;
Mat TempRight;
VideoCapture CapLeft, CapRight;
CapLeft.open(1);
CapRight.open(2);
CapLeft >> TempLeft;
CapRight >> TempRight;
LeftCol = TempLeft.clone();
RightCol = TempRight.clone();
答案 0 :(得分:2)
OpenCV尽可能制作图像的软拷贝。 From the documentation:
数组赋值是O(1)操作,因为它只复制标题并增加引用计数器。 Mat :: clone()方法可用于在需要时获取数组的完整(深层)副本。
我怀疑发生了什么LeftCol
使用仍然属于VideoCapture
对象的数据。如果是这种情况,那么当CapLeft
和CapRight
超出if
末尾的范围时,它们会被析构函数关闭,LeftCol
仍然是VideoCapture CapLeft, CapRight;
的图像数据指着被摧毁。
可能的解决方案是在您正在进行克隆图像,或在if块之外声明{{1}}(如果需要,您仍然可以在里面打开它们。)
答案 1 :(得分:1)
您可以使用cv :: Mat.type()检查类型,使用cv :: Mat.channels()
检查通道数从相机返回的数据将以B,G,R顺序转换为Vec3b(即uchar * 3)。
你确定图像是否有效 - 其他地方是否有错误?
答案 2 :(得分:1)
仅仅因为您尝试了所有Vec *组合,这里是完整列表,我的2ct:
typedef Vec< uchar, 3 > Vec3b (so normal 8 bit)
typedef Vec< double,3 > Vec3d (so normal double precision)
typedef Vec< float, 3 > Vec3f (so normal floating point)
typedef Vec< int, 3 > Vec3i (normal int)
typedef Vec< short, 3 > Vec3s
typedef Vec< ushort 3 > Vec3w (so normal 16 bit)