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