Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Can't find countours

I have some code that finds contours on the Nvidia Jetson. I recently transferred most of the work to the GPU, except for inRange, as there is no GPU function for it, disappointingly. The only problem is that after using the inRange function, when I upload back to the GPU, process, and download, the contours don't show.

Here is my code

Mat imgOriginal;

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

    imshow("Stream", imgOriginal);

    GpuMat g_imgOriginal;
    g_imgOriginal.upload(imgOriginal);
    GpuMat g_imgHSV;
    Mat imgHSV;
    cvtColor(g_imgOriginal, g_imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV

    g_imgHSV.download(imgHSV);
    Mat imgThresholded;
    GpuMat g_imgThresholded;

    inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded); //Threshold the image
    g_imgThresholded.upload(imgThresholded);
    //morphological opening (removes small objects from the foreground)
    gpu::erode(g_imgThresholded, g_imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
    gpu::dilate(g_imgThresholded, g_imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));

    //morphological closing (removes small holes from the foreground)
    gpu::dilate(g_imgThresholded, g_imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
    gpu::erode(g_imgThresholded, g_imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));

    int thresh = 100;
    GpuMat g_canny_output;
    vector<Vec4i> hierarchy;
    vector<vector<Point> > contours;
    RNG rng(12345);

    gpu::Canny(g_imgThresholded, g_canny_output, thresh, thresh * 2, 3);
    /// Find contours
    Mat canny_output;
    g_canny_output.download(canny_output);
    findContours(canny_output, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    /// Draw contours
    Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);
    for (int i = 0; i < contours.size(); i++)
    {
        Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
        drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
    }

    /*This function finds if there are any contours, and if there are
    Then we will first find the center, then add that to a vector(array); This is because there can be more
    than one contours */
    if (contours.size() > 0) {
        for (int i = 0; i < contours.size(); i++) {
            if (cv::contourArea(contours[i]) > 1) {
                cv::Point2f c;
                float r;
                cv::minEnclosingCircle(contours[i], c, r);

                if (r >= minTargetRadius)
                {
                    center.push_back(c);
                    radius.push_back(r);
                }
            }
        }
        size_t count = center.size();
    }

    imshow("contours", drawing);

Can't find countours

(bump)

I have some code that finds contours on the Nvidia Jetson. I recently transferred most of the work to the GPU, except for inRange, as there is no GPU function for it, disappointingly. The only problem is that after using the inRange function, when I upload back to the GPU, process, and download, the contours don't show.

Here is my code

Mat imgOriginal;

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

    imshow("Stream", imgOriginal);

    GpuMat g_imgOriginal;
    g_imgOriginal.upload(imgOriginal);
    GpuMat g_imgHSV;
    Mat imgHSV;
    cvtColor(g_imgOriginal, g_imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV

    g_imgHSV.download(imgHSV);
    Mat imgThresholded;
    GpuMat g_imgThresholded;

    inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded); //Threshold the image
    g_imgThresholded.upload(imgThresholded);
    //morphological opening (removes small objects from the foreground)
    gpu::erode(g_imgThresholded, g_imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
    gpu::dilate(g_imgThresholded, g_imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));

    //morphological closing (removes small holes from the foreground)
    gpu::dilate(g_imgThresholded, g_imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
    gpu::erode(g_imgThresholded, g_imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));

    int thresh = 100;
    GpuMat g_canny_output;
    vector<Vec4i> hierarchy;
    vector<vector<Point> > contours;
    RNG rng(12345);

    gpu::Canny(g_imgThresholded, g_canny_output, thresh, thresh * 2, 3);
    /// Find contours
    Mat canny_output;
    g_canny_output.download(canny_output);
    findContours(canny_output, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    /// Draw contours
    Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);
    for (int i = 0; i < contours.size(); i++)
    {
        Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
        drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
    }

    /*This function finds if there are any contours, and if there are
    Then we will first find the center, then add that to a vector(array); This is because there can be more
    than one contours */
    if (contours.size() > 0) {
        for (int i = 0; i < contours.size(); i++) {
            if (cv::contourArea(contours[i]) > 1) {
                cv::Point2f c;
                float r;
                cv::minEnclosingCircle(contours[i], c, r);

                if (r >= minTargetRadius)
                {
                    center.push_back(c);
                    radius.push_back(r);
                }
            }
        }
        size_t count = center.size();
    }

    imshow("contours", drawing);