From 5579838e85c8ed297a1b89eefc4e30b9dcb8b289 Mon Sep 17 00:00:00 2001 From: ros Date: Mon, 19 May 2025 15:33:42 +0200 Subject: [PATCH] Added RGB configuration (can be changed in comments). --- bin/RedBallDetection | Bin 44048 -> 44048 bytes bin/RedBallTracking | Bin 0 -> 40192 bytes color_params_RGB.xml | 9 ++ lib/RedBallDetection.o | Bin 40464 -> 40456 bytes lib/RedBallTracking.o | Bin 0 -> 41728 bytes makefile | 5 +- src/RedBallDetection.cpp | 48 +++++++- src/RedBallTracking.cpp | 235 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 292 insertions(+), 5 deletions(-) create mode 100755 bin/RedBallTracking create mode 100644 color_params_RGB.xml create mode 100644 lib/RedBallTracking.o create mode 100644 src/RedBallTracking.cpp diff --git a/bin/RedBallDetection b/bin/RedBallDetection index 799977901a3832b7213b9ef3528f45486613c240..cae72c495a38fedc9425d7550b040777359a6124 100755 GIT binary patch delta 1175 zcmYk+du&r>7zXg~J-fKVDqS*cxQq@~*jVXpYhh_*mnvx&htVY}F%ov^x_0SO*bFW@ zq|8hN*Ex8%#3)7*6E~8LKn{{dCsZ-I&8j$+V3=bjI5&nGO!z}0`Fz?r^d#r`z31z9 zdE4Z)@2b*wRXI~hn#tuNbxo?(WTl))$0fj2n-DMLQ zq~)UWqs#gWgzz5uV($1X+spO*UHNwMaZZJi47|0XigesjF;0!DyYi{5^{uNH=Z;KC z>5cA)SH(U`$4FHBeDZ_n%6HY6_l`cVRs@30fm#s?zu-xgo@D7xm2RG>GvzmiL*ceP zd+XckTif^4dfb+d){t-oU4B>C)$VF@abEoo*v6aMrY5;fvh)a)?o{dK6%FIgWnW6^ zOf25T|ErhAlHQv5Z%zZ|cv;(c_~6M=DFY-#{Gyb7@G=~NGoMQN1RTF4Wlx$Ay`M>W z4qk)b!^59T`8WJ#OiClZyY7aR4`&E50)24u7n}$Uvr=Yf3Q-2**v|)N;AtonaZt>m z$XA3g{wif9big_of)UsQPeS(`7Q$CyIu3TsOSuIqH>IqB`7i_6% zDVVu{#$g1m%`gg)K+%Ivx89O+7(NXXun*eMx%iFG`-(^b delta 1200 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 literal 0 HcmV?d00001 diff --git a/color_params_RGB.xml b/color_params_RGB.xml new file mode 100644 index 0000000..7765fb5 --- /dev/null +++ b/color_params_RGB.xml @@ -0,0 +1,9 @@ + + +25 +152 +64 +237 +220 +255 + diff --git a/lib/RedBallDetection.o b/lib/RedBallDetection.o index 1fdfd1d73160f87b7b8b788d4857778a2b6d2eb4..7ebbe51e2cdd473d1372b6edc636b2d56d04ff0f 100644 GIT binary patch delta 923 zcmZ9}O-K}B90u_HPnc#>>cMTrVg*abV$D;r2gmj@MoZKZWU#fa-xI5=tKbIW$04XL zx<2JcyV5Cey2v&i5)2W9EIcR~y5vDbqM;57Asv?NKjU25h55bDzR$}$@5_wN3s2^S z(F)2*ijQ;Y5VN_jaqjdDygJ!ujrH1G-dGmZYTiOBJnOTyD{bvQTPWNon^88R$BZ64 zEW7Az3WvgxKvysl?C1&jWREM_5wf`zcdI+>?r}%l_)zwhx2ZF?@fzD0QMPgPn9-xn zo{v?NU%PfUoJGw@`t8DB8$SD8jwQin{*>cKqwzP3pCzr}{wz@*79Wg|3%3IS@*){n zpk8!0Y|uMg5020mq)e4YnZ6;}xWF^rO)_m`uF1%cnq~Tq#bzT9x5)GppIVIkv{j~k zthE|B)+W<|mTJo;Ax+v&`$0BcLaJ+lYB1G3LLrEeDt`67NFNPiEwVugP3<|%5z+$Q z^t&7-$Bxe3S^EF^Z)*Gf<>Xklu4fF!6SJP2)%0Aj;9YJn4Gujoa-9n7p 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 +#include +#include +#include +#include + +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/imgproc/imgproc.hpp" +#include + +#define CAM_PARAMS_FILENAME "./data/camera_calibration_params.xml" +#define COLOR_PARAMS_FILENAME "./data/color_params.xml" +#define FPS 30.0 +#define STRUCTURAL_ELEMENTS_SIZE 5 +#define AREA_THRESOLD 1000 +#define RESOLUTION_MAX 800 + +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; + int iMaxVideoResolution = RESOLUTION_MAX; + + // updates main parameters from arguments + int opt; + while ((opt = getopt (argc, argv, ":c:f:s:a:i:r:")) != -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 'r': + iMaxVideoResolution = atoi(optarg); + break; + case '?': + if (optopt == 'c' || optopt == 'f' || optopt == 's' || optopt == 'a' | optopt == 'r') + 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 + + // changes image resolution to maximum (e.g. 1920x1080 if possible) + cap.set(cv::CAP_PROP_FRAME_HEIGHT, iMaxVideoResolution); cap.set(cv::CAP_PROP_FRAME_WIDTH, iMaxVideoResolution); + + // 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