From 8426e4722a2912298342d49efc9d72ee0c5fef0e Mon Sep 17 00:00:00 2001 From: Thierry Bissem Date: Fri, 24 May 2024 10:38:12 +0200 Subject: [PATCH] Red Ball Tracking --- bin/RedBallTracking | Bin 0 -> 40136 bytes lib/RedBallTracking.o | Bin 0 -> 40544 bytes makefile | 6 +- src/RedBallTracking.cpp | 227 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 232 insertions(+), 1 deletion(-) create mode 100755 bin/RedBallTracking create mode 100644 lib/RedBallTracking.o create mode 100644 src/RedBallTracking.cpp diff --git a/bin/RedBallTracking b/bin/RedBallTracking new file mode 100755 index 0000000000000000000000000000000000000000..73eeb68c5de4a897082bb1eb9a7daef2ff6491d0 GIT binary patch literal 40136 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 literal 0 HcmV?d00001 diff --git a/lib/RedBallTracking.o b/lib/RedBallTracking.o new file mode 100644 index 0000000000000000000000000000000000000000..7adc78db048cac103d6d5380f437ff66cab4abfc GIT binary patch literal 40544 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 +#include +#include +#include +#include + +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/imgproc/imgproc.hpp" +#include + +#define CAM_PARAMS_FILENAME "./data/microsoft_livecam_hd3000.xml" +#define COLOR_PARAMS_FILENAME "./data/color_params_data.xml" +#define FPS 30.0 +#define STRUCTURAL_ELEMENTS_SIZE 5 +#define AREA_THRESOLD 1000 + +using namespace cv; +using namespace std; + +bool readCameraParameters(std::string filename, cv::Mat &camMatrix, cv::Mat & distCoeffs) +{ + cv::FileStorage fs(filename, cv::FileStorage::READ); + if (!fs.isOpened()) + { + std::cout << "[ERROR] Could not open the camera parameter file storage: " << filename << " !"<< std::endl; + return false; + } + + fs["camera_matrix"] >> camMatrix; + fs["distortion_coefficients"] >> distCoeffs; + + return true; +} + +bool readColorParameters(std::string filename, int& iLowH, int& iHighH, int& iLowS, int& iHighS, int& iLowV, int& iHighV) +{ + cv::FileStorage fs(filename, cv::FileStorage::READ); + if (!fs.isOpened()) + { + std::cout << "[ERROR] Could not open the color paramter file storage: " << filename << " !"<< std::endl; + return false; + } + + fs["lowH"] >> iLowH; + fs["highH"] >> iHighH; + + fs["lowS"] >> iLowS; + fs["highS"] >> iHighS; + + fs["lowV"] >> iLowV; + fs["highV"] >> iHighV; + + return true; +} + + int main( int argc, char** argv ) + { + // initializes main parameters + std::string sCameraParamFilename = CAM_PARAMS_FILENAME; + std::string sColorParamFilename = COLOR_PARAMS_FILENAME; + float fFPS = FPS; + int iStructuralElementSize = STRUCTURAL_ELEMENTS_SIZE; + int iAreaThresold = AREA_THRESOLD; + + // updates main parameters from arguments + int opt; + while ((opt = getopt (argc, argv, ":c:f:s:a:i:")) != -1) + { + switch (opt) + { + case 'c': + sColorParamFilename = optarg; + break; + case 'f': + fFPS = atof(optarg); + break; + case 's': + iStructuralElementSize = atoi(optarg); + break; + case 'a': + iAreaThresold = atoi(optarg); + break; + case 'i': + sCameraParamFilename = optarg; + break; + case '?': + if (optopt == 'c' || optopt == 'f' || optopt == 's' || optopt == 'a') + fprintf (stderr, "Option -%c requires an argument.\n", optopt); + else if (isprint (optopt)) + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); + return 1; + default: + abort (); + } + } + + // reads color parameters from the file storage + int iLowH, iHighH, iLowS, iHighS, iLowV, iHighV; + bool isColorParamsSet = readColorParameters(sColorParamFilename, iLowH, iHighH, iLowS, iHighS, iLowV, iHighV); + + // checks if the color parameters were successfully read + if (!isColorParamsSet) + { + std::cout << "[ERROR] Color parameters could not be loaded!" << std::endl; + return -1; + } + + // distorted/undistorted image + bool bIsImageUndistorted = true; + + // reads camera intrinsic parameters + cv::Mat cameraMatrix, distCoeffs; + bool isCamParamsSet = readCameraParameters(sCameraParamFilename, cameraMatrix, distCoeffs); + + // checks if the camera parameters were successfully read + if (!isCamParamsSet) + { + std::cout << "[WARNING] Camera intrinsic parameters could not be loaded!" << std::endl; + } + + // creates a camera grabber + VideoCapture cap(0, cv::CAP_V4L2); //capture the video from webcam + + // checks if the camera was successfully opened + if ( !cap.isOpened() ) // if not success, exit program + { + cout << "[ERROR] Could not open the camera!" << endl; + return -1; + } + + // inits previous x,y location of the ball + int iLastX = -1; + int iLastY = -1; + + // captures a temporary image from the camera + Mat imgTmp; + cap.read(imgTmp); + + // creates a black image with the size as the camera output + Mat imgLines = Mat::zeros( imgTmp.size(), CV_8UC3 ); + + // main loop launched every FPS + while (true) + { + // reads a new frame from video + cv::Mat imgOriginal; + bool bSuccess = cap.read(imgOriginal); + + // checks if a new frame was grabbed + if (!bSuccess) //if not success, break loop + { + std::cout << "[WARNING] Could not read a new frame from video stream" << std::endl; + break; + } + + if (bIsImageUndistorted && isCamParamsSet) + { + cv::Mat temp = imgOriginal.clone(); + cv::undistort(temp, imgOriginal, cameraMatrix, distCoeffs); + } + + // converts the captured frame from BGR to HSV + cv::Mat imgHSV; + cvtColor(imgOriginal, imgHSV, cv::COLOR_BGR2HSV); + + // thresholds the image based on the trackbar values + cv::Mat imgThresholded; + inRange(imgHSV, cv::Scalar(iLowH, iLowS, iLowV), cv::Scalar(iHighH, iHighS, iHighV), imgThresholded); + + // applies morphological opening (removes small objects from the foreground) + cv::erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(iStructuralElementSize, iStructuralElementSize)) ); + cv::dilate( imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(iStructuralElementSize, iStructuralElementSize)) ); + + // applies morphological closing (removes small holes from the foreground) + cv::dilate( imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(iStructuralElementSize, iStructuralElementSize)) ); + cv::erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(iStructuralElementSize, iStructuralElementSize)) ); + + // calculates the moments of the thresholded image + Moments oMoments = moments(imgThresholded); + double dM01 = oMoments.m01; + double dM10 = oMoments.m10; + double dArea = oMoments.m00; + + // if the area <= iAreaThresold, considers that the there are no object in the image and it's because of the noise, the area is not zero + if (dArea > iAreaThresold) + { + // calculates the position of the ball + int posX = dM10 / dArea; + int posY = dM01 / dArea; + + if (iLastX >= 0 && iLastY >= 0 && posX >= 0 && posY >= 0) + { + // draww a red line from the previous point to the current point + line(imgLines, Point(posX, posY), Point(iLastX, iLastY), Scalar(0,0,255), 2); + } + + // stores the current position for enxt frame + iLastX = posX; + iLastY = posY; + } + + // displays the thresholded image + imshow("Thresholded Image", imgThresholded); + + // shows the original image with the tracking (red) lines + imgOriginal = imgOriginal + imgLines; + imshow("Original", imgOriginal); + + // waits for awhile depending on the FPS value + char key = (char)cv::waitKey(1000.0/fFPS); + // checks if ESC was pressed to exit + if (key == 27) // if 'esc' key is pressed, break loop + { + std::cout << "[INFO] esc key is pressed by user -> Shuting down!" << std::endl; + break; + } + if (key == 'u') + { + bIsImageUndistorted = !bIsImageUndistorted; + std::cout << "[INFO] Image undistorted: " << bIsImageUndistorted<< std::endl; + } + } + + return 0; +} \ No newline at end of file