OpenCV将Mat Object转换为C ++中的数组

时间:2014-09-08 14:59:33

标签: c++ arrays opencv image-processing

我正在尝试使用OpenCV从网络摄像头抓取帧并将其转换为HSV(Hue,Saturation,Value)Mat对象。

现在我需要将HSV Mat对象转换为存储像素值的数组。

这是我现在所做的最远的事情。

int main()
 {
     Mat imgOriginal;
    VideoCapture cap(0); //capture the video from web cam
    int camOpen = cap.open(CV_CAP_ANY);




    if ( !cap.isOpened() )  // if not success, exit program
    {
         cout << "Cannot open the web cam" << endl;
         return -1;
    }

    namedWindow("Control", CV_WINDOW_AUTOSIZE); //create a window called "Control"

    int iLowH = 0;
    int iHighH = 179;

    int iLowS = 0; 
    int iHighS = 255;

    int iLowV = 0;
    int iHighV = 255;

    //Create trackbars in "Control" window
    cvCreateTrackbar("LowH", "Control", &iLowH, 179); //Hue (0 - 179)
    cvCreateTrackbar("HighH", "Control", &iHighH, 179);

    cvCreateTrackbar("LowS", "Control", &iLowS, 255); //Saturation (0 - 255)
    cvCreateTrackbar("HighS", "Control", &iHighS, 255);

    cvCreateTrackbar("LowV", "Control", &iLowV, 255); //Value (0 - 255)
    cvCreateTrackbar("HighV", "Control", &iHighV, 255);

    time_t start, end;
    int counter = 0;
    time(&start);

    while (true)
    {
        time(&end);
        counter++;    
        if(1<difftime (end, start))
        {
            cout<<"fps"<<counter<<endl;
            counter=0;
            time(&start);

            cout<<"iHighH :"<<iLowH<<endl;
            cout<<"iHighS :"<<iLowS<<endl;
            cout<<"iHighV :"<<iLowV<<endl;
        }

        cap >> imgOriginal;

        bool bSuccess = cap.read(imgOriginal); // read a new frame from video

        if (!bSuccess) //if not success, break loop
        {
             cout << "Cannot read a frame from video stream" << endl;
             break;
        }
        Mat imgHSV;

        cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV

        Mat imgThresholded;
        inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded); //Threshold the image

        //morphological opening (remove small objects from the foreground)
        erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );
        dilate( imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) ); 

        //morphological closing (fill small holes in the foreground)
        dilate( imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) ); 
        erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );




        //
        //  CONVERT imgHSV object in to an array 
        //




        imshow("Thresholded Image", imgThresholded); //show the thresholded image
        imshow("Original", imgOriginal); //show the original image

        if (waitKey(30) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
        {
            cout << "esc key is pressed by user" << endl;
            break; 
         }
    }
    system("pause");
    return 0;
}

1 个答案:

答案 0 :(得分:3)

这会将图像像素复制到矢量中。如果您需要类似C的数组,请使用&pixels[0]

std::vector<cv::Vec3b> pixels;

cv::MatIterator_<Vec3b> it, end;
for(it = imgHSV .begin<Vec3b>(), end = imgHSV.end<Vec3b>(); it != end; ++it)
{
    pixels.push_back(*it);
}

这是一种更有效的填充像素矢量的方法:

std::vector<cv::Vec3b> pixels(imgHSV.rows * imgHSV.cols);
cv::Mat m(imgHSV.rows, imgHSV.cols, CV_8UC3, &pixels[0]);
imgHSV.copyTo(m);