OpenCV在C++中将Mat对象转换为数组

OpenCV convert Mat Object to array in C++

本文关键字:转换 数组 对象 Mat C++ 中将 OpenCV      更新时间:2023-10-16

我正试图使用OpenCV从网络摄像头获取帧,并将其转换为HSV(色调、饱和度、值)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;
}

这将把图像像素复制到一个向量中。如果您需要一个类似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);