0

我正在尝试在 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,v0,0. 我不知道为什么它不起作用。我已经尝试了所有变Vec3b体,,,,,Vec3iVec3sVec3fVec3d

我迷路了......为什么我不能索引这个网络摄像头图像?

编辑

就这样,几个小时后,这就是我必须要去的地方……这是程序的大纲。我在函数内部遇到了上面提到的问题。所以我回到了基础,试图在函数之前查看矩阵......

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();
4

3 回答 3

2

OpenCV makes soft copies of images whenever possible. From the documentation:

the array assignment is an O(1) operation because it only copies the header and increases the reference counter. The Mat::clone() method can be used to get a full (deep) copy of the array when you need it.

I suspect what is happening is LeftCol uses data which still belongs with the VideoCapture object. If this is the case then when CapLeft and CapRight go out of scope at the end of the if they are closed by the destructor and the image data which LeftCol is still pointing to is destroyed.

Possible solutions would be to clone the image as you are doing, or declare VideoCapture CapLeft, CapRight; outside of the if block (you can still open them inside if needed).

于 2012-09-18T10:48:03.540 回答
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)
于 2014-02-01T23:45:45.073 回答
1

您可以使用 cv::Mat.type() 检查类型,使用 cv::Mat.channels() 检查通道数

摄像头返回的数据会按照B、G、R的顺序转换成Vec3b(即uchar * 3)。

你确定图像是有效的 - 其他地方有错误吗?

于 2012-09-17T15:06:20.267 回答