{"id":1719,"date":"2026-03-06T15:21:00","date_gmt":"2026-03-06T23:21:00","guid":{"rendered":"http:\/\/macdaddy4sure.ai\/?p=1719"},"modified":"2026-04-23T17:22:53","modified_gmt":"2026-04-24T00:22:53","slug":"_ball","status":"publish","type":"post","link":"http:\/\/macdaddy4sure.ai\/index.php\/2026\/03\/06\/_ball\/","title":{"rendered":"_Ball"},"content":{"rendered":"\n<p>General sports ball tracker and calculus integrated into _AI.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/*\n    Copyright(C) 2025 Tyler Crockett | Macdaddy4sure.ai\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n    http:&#47;&#47;www.apache.org\/licenses\/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissionsand\n    limitations under the License.\n*\/\n\n#include \"AugmentedIntelligence.hpp\"\n#include \"Ball.hpp\"\n#include \"Working-Memory.hpp\"\n#include \"Short-Term Memory.hpp\"\n#include \"Long-Term Memory.hpp\"\n#include \"Settings.hpp\"\n#include \"Sound.hpp\"\n#include \"Vision.hpp\"\n\nusing namespace std;\n\n\/\/ Ball is life... there will be no other. Sports are life; was it me?\n\/\/ Should ball have its own detector? Should I leave ball tracking to Vision.cpp?\n\/\/ 1. Sports Ball Detector Neural Network\n\/\/ 2. Sports Ball Distance\n\/\/ 3. Sports Ball IoU\n\/\/ 4. Sports Ball Velocity\n\/\/ 5. Sports Ball Accelleration\n\/\/ 6. Sports Ball Path Prediction\n\nvoid _Ball::BallHeuristicInit()\n{\n    Object my_car;\n    Object current_object;\n    Object prev_object;\n\n    if (vision_object_detection)\n    {\n        TF_Status* status = TF_NewStatus();\n        TF_Graph* graph = TF_NewGraph();\n        TF_SessionOptions* options = TF_NewSessionOptions();\n        TF_Buffer* run_opts = nullptr;\n        const char* tags = \"serve\";\n        TF_Session* session = TF_LoadSessionFromSavedModel(options, nullptr, tensorflow_model.c_str(), &amp;tags, 1, graph, nullptr, status);\n\n        for (;;)\n        {\n            cv::Mat frame;\n\n            \/\/ Find the last image and use that image for object detection\n            for (int x = 999; x >= 0; x--)\n            {\n                if (!stm_vision_path_camera1&#91;x]&#91;0].empty())\n                {\n                    frame = cv::imread(stm_vision_path_camera1&#91;x]&#91;0]);\n\n                    \/\/ Check the hash of the image?\n\n                    \/\/ Store the current image inside the ball memory array\n                    for (int y = 0; y &lt; 999; y++)\n                    {\n                        if (wm_ball&#91;y]&#91;0].empty())\n                        {\n                            \/\/\/\/lock_guard&lt;mutex> lock(\/\/mtx_stm_vision_path_camera1&#91;x]&#91;0]);\n                            \/\/\/\/lock_guard&lt;mutex> lock1(\/\/mtx_stm_vision_path_camera1&#91;x]&#91;1]);\n                            wm_ball&#91;y]&#91;0] = stm_vision_path_camera1&#91;x]&#91;0];\n                            wm_ball&#91;y]&#91;1] = stm_vision_path_camera1&#91;x]&#91;1];\n                        }\n                    }\n                    break;\n                }\n            }\n\n            vector&lt;vector&lt;string>> coco_ball = _Ball::ObjectDetection::ObjectDetectionBall(status, graph, options, run_opts, tags, session, frame);\n\n            \/\/ Read the values from the coco_ball array and store them into memory\n            for (int x = 0; x &lt;= coco_ball.size(); x++)\n            {\n                if (coco_ball&#91;x]&#91;1] == \"sports ball\")\n                {\n                    current_object.unique_id = \"object \" + to_string(x);\n                    current_object.class_name = coco_ball&#91;x]&#91;1];\n                    current_object.x = stoi(coco_ball&#91;x]&#91;2]);\n                    current_object.box_width = stoi(coco_ball&#91;x]&#91;3]);\n                    current_object.y = stoi(coco_ball&#91;x]&#91;4]);\n                    current_object.box_height = stoi(coco_ball&#91;x]&#91;5]);\n                    current_object.distance = _Ball::Math::getBallDistance(current_object, prev_object);\n                }\n            }\n\n            if (current_object.class_name == prev_object.class_name)\n            {\n                double IoU = _Ball::Math::CalculateIoU(current_object, prev_object);\n\n                if (IoU >= iou_min &amp;&amp; IoU &lt;= iou_max)\n                {\n                    current_object.velocity = _Ball::Math::CalculateObjectVelocity(current_object, prev_object, 1 \/ camera1_fps);\n                    current_object.acceleration = _Ball::Math::CalculateAcceleration(current_object, prev_object, 1 \/ camera1_fps);\n\n                    \/\/ Get the probability of collision from this data\n                    double relativeVelocity = _Ball::Math::calculateRelativeVelocity(my_car, current_object);\n\n                    cv::Rect currentRect(current_object.x, current_object.y, current_object.box_width, current_object.box_height);\n\n                    cv::rectangle(frame, currentRect, cv::Scalar(0, 255, 0), 2);\n                    std::string label = \"Velocity: \" + std::to_string((int)current_object.velocity) + \" mph\";\n                    cv::putText(frame, label, cv::Point(currentRect.x, currentRect.y - 10),\n                        cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 0), 2);\n                }\n            }\n\n            \/\/ Save the coordinates to the current array\n            \/\/ How to save individual vehicles into memory and access that memory\n            \/\/ Find the first empty position in the array\n            \/\/ Get the previous object's data\n            prev_object.unique_id = current_object.unique_id;\n            prev_object.class_name = current_object.class_name;\n            prev_object.x = current_object.x;\n            prev_object.box_width = current_object.box_width;\n            prev_object.y = current_object.y;\n            prev_object.box_height = current_object.box_height;\n            prev_object.distance = current_object.distance;\n            prev_object.velocity&#91;0] = current_object.velocity&#91;0];\n            prev_object.velocity&#91;1] = current_object.velocity&#91;1];\n            prev_object.acceleration&#91;0] = current_object.acceleration&#91;0];\n            prev_object.acceleration&#91;1] = current_object.acceleration&#91;1];\n        }\n    }\n    else\n    {\n        vision_object_detection = false;\n    }\n}\n\nvector&lt;vector&lt;string>> _Ball::ObjectDetection::ObjectDetectionBall(TF_Status* status, TF_Graph* graph, TF_SessionOptions* options, TF_Buffer* run_opts, const char* tags, TF_Session* session, Mat frame)\n{\n    string current_date;\n    ostringstream oss;\n    auto entry = time(nullptr);\n    auto tm1 = *localtime(&amp;entry);\n\n    oss &lt;&lt; put_time(&amp;tm1, \"%d-%m-%Y_%H-%M-%S\");\n    current_date = oss.str();\n\n    \/\/std::string imagePath = \"D:\/_test\/saved_sequence2\/\";\n    \/\/ Debug\n    \/\/std::string model_path = \"D:\/_AugmentedIntelligence\/_src\/tensorflow_models\/coco_object_detection\/saved_model\/\";\n    \/\/std::string labelsPath = \"D:\/_AugmentedIntelligence\/_src\/tensorflow_models\/coco_object_detection\/coco.names\";\n\n    \/\/ Convert image to tensor\n    TF_Tensor* inputTensor = _Vision::MatToTensor(frame);\n\n    \/\/ Define input operation\n    TF_Output input_op = { TF_GraphOperationByName(graph, \"serving_default_input_tensor\"), 0 };\n\n    \/\/ Define output operations\n    std::vector&lt;TF_Output> output_ops{\n        { TF_GraphOperationByName(graph, \"StatefulPartitionedCall\"), 1 },\n        { TF_GraphOperationByName(graph, \"StatefulPartitionedCall\"), 2 },\n        { TF_GraphOperationByName(graph, \"StatefulPartitionedCall\"), 4 },\n    };\n\n    std::vector&lt;TF_Tensor*> input_tensors = { inputTensor };\n    TF_Tensor* output_tensors&#91;] = { NULL, NULL, NULL };\n\n    if (TF_GetCode(status) != TF_OK)\n    {\n        fprintf(stderr, \"Error: %s\\n\", TF_Message(status));\n        \/\/ Handle error appropriately\n    }\n\n    \/\/ Run the session\n    TF_SessionRun(session, nullptr,\n        &amp;input_op, input_tensors.data(), input_tensors.size(),\n        output_ops.data(), output_tensors, output_ops.size(),\n        nullptr, 0, nullptr, status);\n\n    if (TF_GetCode(status) == TF_OK)\n    {\n        printf(\"Session run successfully\\n\");\n    }\n    else\n    {\n        fprintf(stderr, \"Session run error: %s\\n\", TF_Message(status));\n    }\n\n    \/\/ Debug\n    cout &lt;&lt; \"output_tensors&#91;0]: \" &lt;&lt; output_tensors&#91;0] &lt;&lt; endl;\n    cout &lt;&lt; \"output_tensors&#91;1]: \" &lt;&lt; output_tensors&#91;1] &lt;&lt; endl;\n    cout &lt;&lt; \"output_tensors&#91;2]: \" &lt;&lt; output_tensors&#91;2] &lt;&lt; endl;\n    \/\/cin.get();\n\n    \/\/ Process the output tensors to extract boxes, scores, and class IDs\n    auto boxes = _Vision::ExtractBoxes(output_tensors&#91;0], frame.size()); \/\/ Needs implementation\n    auto classIds = _Vision::ExtractClassIds(output_tensors&#91;1]); \/\/ Needs implementation\n    auto scores = _Vision::ExtractScores(output_tensors&#91;2]); \/\/ Needs implementation\n    std::vector&lt;string> classLabels = _Vision::LoadLabels(tensorflow_labels);\n    cout &lt;&lt; \"classIds: \" &lt;&lt; classIds&#91;0] &lt;&lt; endl;\n\n    _Vision::DrawBoundingBoxes(frame, boxes, classIds, scores, classLabels);\n\n    \/\/ Debug\n    std::string temp = vision_memory_directory;\n    temp += \"\/camera1\/driving\/object_detection\/\";\n    temp += current_date.c_str();\n    temp += \"_object_detection_camera1.png\";\n    std::cout &lt;&lt; \"Writing image: \" &lt;&lt; temp &lt;&lt; std::endl;\n    cv::imwrite(temp.c_str(), frame);\n\n    vector&lt;vector&lt;string>> return_array;\n\n    \/\/ Create the return array\n    for (int i = 0; i &lt; boxes.size(); i++)\n    {\n        const auto&amp; box = boxes&#91;i];\n        int classId = classIds&#91;i];\n        float score = scores&#91;i];\n\n        if (score >= 0.90)\n        {\n            vector&lt;string> row(7);\n            row&#91;0] = temp;\n            cout &lt;&lt; row&#91;0] &lt;&lt; endl;\n            row&#91;1] = classLabels&#91;classId - 1]; \/\/ Use the actual class ID instead of x\n            cout &lt;&lt; row&#91;1] &lt;&lt; endl;\n            row&#91;2] = to_string(box.x);\n            cout &lt;&lt; row&#91;2] &lt;&lt; endl;\n            row&#91;3] = to_string(box.width);\n            cout &lt;&lt; row&#91;3] &lt;&lt; endl;\n            row&#91;4] = to_string(box.y);\n            cout &lt;&lt; row&#91;4] &lt;&lt; endl;\n            row&#91;5] = to_string(box.height);\n            cout &lt;&lt; row&#91;5] &lt;&lt; endl;\n            row&#91;6] = to_string(score);\n            cout &lt;&lt; row&#91;6] &lt;&lt; endl;\n\n            return_array.push_back(row);\n        }\n    }\n\n    \/\/ Cleanup\n    \/\/TF_DeleteTensor(inputTensor);\n    \/\/TF_DeleteTensor(output_tensors&#91;0]);\n    \/\/TF_DeleteTensor(output_tensors&#91;1]);\n    \/\/TF_DeleteTensor(output_tensors&#91;2]);\n    \/\/TF_DeleteSession(session, status);\n    \/\/TF_DeleteSessionOptions(options);\n    \/\/TF_DeleteStatus(status);\n\n    return return_array;\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>General sports ball tracker and calculus integrated into _AI.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1719","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"http:\/\/macdaddy4sure.ai\/index.php\/wp-json\/wp\/v2\/posts\/1719","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/macdaddy4sure.ai\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/macdaddy4sure.ai\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/macdaddy4sure.ai\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/macdaddy4sure.ai\/index.php\/wp-json\/wp\/v2\/comments?post=1719"}],"version-history":[{"count":4,"href":"http:\/\/macdaddy4sure.ai\/index.php\/wp-json\/wp\/v2\/posts\/1719\/revisions"}],"predecessor-version":[{"id":1734,"href":"http:\/\/macdaddy4sure.ai\/index.php\/wp-json\/wp\/v2\/posts\/1719\/revisions\/1734"}],"wp:attachment":[{"href":"http:\/\/macdaddy4sure.ai\/index.php\/wp-json\/wp\/v2\/media?parent=1719"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/macdaddy4sure.ai\/index.php\/wp-json\/wp\/v2\/categories?post=1719"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/macdaddy4sure.ai\/index.php\/wp-json\/wp\/v2\/tags?post=1719"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}