├── AutoDetectionOpenCV ├── ak.png ├── lr.PNG ├── AutoDetectionOpenCV.vcxproj.user ├── AutoDetectionOpenCV.vcxproj.filters ├── AutoDetectionOpenCV.vcxproj └── AutoDetectionOpenCV.cpp ├── README.md └── AutoDetectionOpenCV.sln /AutoDetectionOpenCV/ak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YouNeverKnow00/Rust-Auto-Weapon-Detection-OpenCV-Example/HEAD/AutoDetectionOpenCV/ak.png -------------------------------------------------------------------------------- /AutoDetectionOpenCV/lr.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YouNeverKnow00/Rust-Auto-Weapon-Detection-OpenCV-Example/HEAD/AutoDetectionOpenCV/lr.PNG -------------------------------------------------------------------------------- /AutoDetectionOpenCV/AutoDetectionOpenCV.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rust-Auto-Weapon-Detection-OpenCV-Example 2 | 3 | Example project for Rust auto weapon detect with OpenCV. 4 | 5 | I'm posting these sample codes here because I don't have time to deal with the script. 6 | 7 | I hope it will be useful for you and have fun xD 8 | 9 | Pictures 10 | 11 | 1) ![alt text](https://i.hizliresim.com/p8jveuu.png) 12 | 13 | 2) ![alt text](https://i.hizliresim.com/qp2aulf.png) 14 | 15 | # 16 | Credits: febee#1533 17 | -------------------------------------------------------------------------------- /AutoDetectionOpenCV/AutoDetectionOpenCV.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /AutoDetectionOpenCV.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31205.134 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AutoDetectionOpenCV", "AutoDetectionOpenCV\AutoDetectionOpenCV.vcxproj", "{AF6AF284-685A-49C8-A485-A5A7E0656F5D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {AF6AF284-685A-49C8-A485-A5A7E0656F5D}.Debug|x64.ActiveCfg = Debug|x64 17 | {AF6AF284-685A-49C8-A485-A5A7E0656F5D}.Debug|x64.Build.0 = Debug|x64 18 | {AF6AF284-685A-49C8-A485-A5A7E0656F5D}.Debug|x86.ActiveCfg = Debug|Win32 19 | {AF6AF284-685A-49C8-A485-A5A7E0656F5D}.Debug|x86.Build.0 = Debug|Win32 20 | {AF6AF284-685A-49C8-A485-A5A7E0656F5D}.Release|x64.ActiveCfg = Release|x64 21 | {AF6AF284-685A-49C8-A485-A5A7E0656F5D}.Release|x64.Build.0 = Release|x64 22 | {AF6AF284-685A-49C8-A485-A5A7E0656F5D}.Release|x86.ActiveCfg = Release|Win32 23 | {AF6AF284-685A-49C8-A485-A5A7E0656F5D}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {8AC9B7A6-70E1-475B-8521-8C24C895604A} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /AutoDetectionOpenCV/AutoDetectionOpenCV.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {af6af284-685a-49c8-a485-a5a7e0656f5d} 25 | AutoDetectionOpenCV 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | 79 | 80 | true 81 | F:\opencv\sources\modules;F:\opencv\build\include;$(IncludePath) 82 | F:\opencv\sources\modules;F:\opencv\build\lib;F:\opencv\build\lib\Debug;F:\opencv\build\x64\vc15\lib;$(LibraryPath) 83 | 84 | 85 | false 86 | 87 | 88 | 89 | Level3 90 | true 91 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 92 | true 93 | 94 | 95 | Console 96 | true 97 | 98 | 99 | 100 | 101 | Level3 102 | true 103 | true 104 | true 105 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 106 | true 107 | 108 | 109 | Console 110 | true 111 | true 112 | true 113 | 114 | 115 | 116 | 117 | Level3 118 | true 119 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 120 | true 121 | 122 | 123 | Console 124 | true 125 | opencv_world452d.lib;%(AdditionalDependencies) 126 | 127 | 128 | 129 | 130 | Level3 131 | true 132 | true 133 | true 134 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 135 | true 136 | 137 | 138 | Console 139 | true 140 | true 141 | true 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /AutoDetectionOpenCV/AutoDetectionOpenCV.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "opencv2/core.hpp" 6 | 7 | #include "opencv2/highgui.hpp" 8 | #include "opencv2/features2d.hpp" 9 | #include "opencv2/imgcodecs.hpp" 10 | #include "opencv2/imgproc.hpp" 11 | 12 | #include "opencv2/video/background_segm.hpp" 13 | 14 | // 15 | bool test; 16 | 17 | using namespace cv; 18 | std::vector rgbValues = { 19 | Scalar(114,98,115), 20 | Scalar(112,70,140), 21 | Scalar(70, 70, 180), 22 | Scalar(117, 30, 140), 23 | Scalar(112, 30, 120), 24 | }; 25 | struct RGB { 26 | int r = 0; 27 | int g = 0; 28 | int b = 0; 29 | }rgb; 30 | 31 | void filter_RGB_VALUES(std::vector rgbValues) { 32 | std::cout << rgbValues.size(); 33 | for (int i = 0; i < rgbValues.size(); i++) 34 | { 35 | if (rgbValues[i][2] > 180 || rgbValues[i][2] < 120) { 36 | rgbValues.erase(rgbValues.begin() + i); 37 | } 38 | } 39 | std::cout << rgbValues.size() << "\n"; 40 | std::vector rgb_Averages; 41 | for (int i = 0; i < rgbValues.size(); i++) 42 | { 43 | rgb_Averages.push_back({ 0,0,0 }); 44 | rgb_Averages[0].r += rgbValues[i][0]; 45 | rgb_Averages[0].g += rgbValues[i][1]; 46 | rgb_Averages[0].b += rgbValues[i][2]; 47 | std::cout << rgbValues[i][0] << " " << rgbValues[i][1] << " " << rgbValues[i][2] << "\n"; 48 | } 49 | rgb_Averages[1].r = rgb_Averages[0].r / rgbValues.size(); 50 | rgb_Averages[1].g = rgb_Averages[0].g / rgbValues.size(); 51 | rgb_Averages[1].b = rgb_Averages[0].b / rgbValues.size(); 52 | for (int i = 0; i < rgbValues.size(); i++) 53 | { 54 | 55 | rgb_Averages[2].r += pow((rgbValues[i][0] - rgb_Averages[1].r), 2); 56 | rgb_Averages[2].g += pow((rgbValues[i][1] - rgb_Averages[1].g), 2); 57 | rgb_Averages[2].b += pow((rgbValues[i][2] - rgb_Averages[1].b), 2); 58 | } 59 | //Calculate Standard Deviation of R,G,B Values 60 | int stdevR = sqrt(rgb_Averages[2].r / rgbValues.size()); 61 | int stdevG = sqrt(rgb_Averages[2].g / rgbValues.size()); 62 | int stdevB = sqrt(rgb_Averages[2].b / rgbValues.size()); 63 | std::cout << "R MEAN : " << rgb_Averages[1].r << " G MEAN: " << rgb_Averages[1].g << " B MEAN: " << rgb_Averages[1].b << "\n"; 64 | std::cout << "R STDEV: " << stdevR << " G STDEV: " << stdevG << " B STDEV " << stdevB << "\n"; 65 | for (int i = 0; i < rgbValues.size(); i++) 66 | { 67 | int outlier = (rgbValues[i][2] < rgb_Averages[1].b) ? (rgbValues[i][2] + stdevB) : (rgbValues[i][2] - stdevB); 68 | std::cout << "Deviation " << outlier << std::endl; 69 | if (abs(outlier - rgb_Averages[1].b) > stdevB) { 70 | std::cout << "Outlier: " << rgbValues[1][2]; 71 | } 72 | } 73 | 74 | } 75 | 76 | 77 | //int findSlot(int width, int height, float UISCALE, double resScale) 78 | //{ 79 | // HDC hScreen = GetDC(NULL); 80 | // int result = 0; 81 | // int avgRGBBlue = 0; 82 | // double widthScale = (double(width) / 1920.0); 83 | // //double heightScale = (double(height) / 1080.0); 84 | // int mid_x = 660.0 * 1.0 / UISCALE * (widthScale); 85 | // int mid_y = 96.0 * UISCALE * (widthScale); 86 | // int sizeOfSlot = 90.0 * UISCALE * (widthScale); 87 | // int ypixel = (height)-(27.0 * widthScale * UISCALE) - sizeOfSlot; 88 | // for (int i = 0; i < 6; i++) { 89 | // int xpixel = ((width - (24.0 * UISCALE * widthScale)) / 2.0) - ((mid_y * 6.0) / 2.0) + (mid_y * i); 90 | // Point start = Point(xpixel, ypixel); 91 | // Point scanThis = Point(start.x + (30 * resScale), start.y + (20 * resScale)); 92 | // int SCLR = GetBValue(GetPixel(hScreen, scanThis.x, scanThis.y)); 93 | // //fprintf(fptr, "Scanning Slot %d at X: %d Y: %d, B Value is %d\n", i, scanThis.x, scanThis.y, SCLR); 94 | // if (SCLR > 130 && SCLR < 170) 95 | // { 96 | // //fprintf(fptr, "Slot is: %d\n", (int)i); 97 | // return (i + 1.0); 98 | // } 99 | // } 100 | // return 0; 101 | //} 102 | struct weaponToIndex { 103 | int i; 104 | std::string name; 105 | }weaponToIndex; 106 | std::vector weaponsIDX = { 107 | {0, "AK"}, 108 | {1,"MP5"}, 109 | {2, "LR300"}, 110 | {3, "M249"}, 111 | {4, "Semi"}, 112 | {5, "M39"}, 113 | {6, "Thompson"}, 114 | {7, "CustomSMG"}, 115 | {8, "Python"}, 116 | {9, "Semi-Skin"}, 117 | {10, "Thompson-Skin"}, 118 | {11, "Custom-default"}, 119 | {12, "M92"} 120 | }; 121 | 122 | int main() 123 | { 124 | auto start = std::chrono::high_resolution_clock::now(); 125 | Mat img = imread("./lr.png"); 126 | Mat scene; 127 | //filter_RGB_VALUES(rgbValues); 128 | //cvtColor(img, img, COLOR_GRAY2RGB); 129 | int width = img.cols; 130 | int height = img.rows; 131 | float UISCALE = 1.0; 132 | int probablyIndex = 0; 133 | double resScale = ((width * height) / (1920.0 * 1080.0)); 134 | double widthScale = (double(width) / 1920.0); 135 | double heightScale = (double(height) / 1080.0); 136 | int mid_x = 660.0 * 1.0 / UISCALE * (widthScale); 137 | int mid_y = 96.0 * UISCALE * (widthScale); 138 | int sizeOfSlot = 90.0 * UISCALE * (widthScale); 139 | int ypixel = (height)-(27.0 * widthScale * UISCALE) - sizeOfSlot; 140 | Mat rslt, mask, savedResult; 141 | std::vector keypoints_obj, keypoints_scene; 142 | Mat descriptors_box, descriptors_sence, foregroundMask, backgroundImage, foregroundIMG; 143 | int highestSimilarity = 0; 144 | int similiarityCount = 0; 145 | for (int i = 0; i < 6; i++) { 146 | auto startIter = std::chrono::high_resolution_clock::now(); 147 | int xpixel = ((width - (24.0 * UISCALE * widthScale)) / 2.0) - ((mid_y * 6.0) / 2.0) + (mid_y * i); 148 | Point start = Point(xpixel, ypixel); 149 | Point scanThis = Point(start.x + (13 * resScale), start.y + (30 * resScale)); 150 | Rect cropRegion = Rect2i(Rect(start.x, start.y, mid_y, mid_y)); 151 | Mat cropped = img(cropRegion); 152 | std::cout << cropped.cols << " " << cropped.rows << std::endl; 153 | resize(cropped, cropped, Size(), 90.0 / cropped.cols, 90.0 / cropped.rows); 154 | 155 | std::cout << cropped.cols << " " << cropped.rows << std::endl; 156 | //waitKey 157 | resize(cropped, cropped, Size(), 3, 3); 158 | imshow("cropped", cropped); 159 | //imshow("resized", cropped); 160 | std::cout << cropped.cols << " " << cropped.rows << std::endl; 161 | //waitKey(); 162 | //circle(img, scanThis, 2, Scalar(0, 255, 0), 1); 163 | //threshold(cropped, cropped, 130, 220, THRESH_BINARY); 164 | //cv::Mat holes = cropped.clone(); 165 | /*imshow("threshed1", cropped); 166 | waitKey();*/ 167 | savedResult = cropped; 168 | Mat dst, detectedEdges; 169 | //GaussianBlur(cropped, cropped, Size(), 3, 3); 170 | inRange(cropped, Scalar(130, 0, 0), Scalar(250, 150, 150), mask); 171 | Scalar color = mean(mask, noArray()); 172 | dst = Scalar::all(0); 173 | 174 | //Mat im_in = mask; 175 | //rectangle(im_in, Rect2i(Rect(185, 190, 60, 60)), Scalar(255, 255, 255), -1); 176 | //rectangle(im_in, Rect2i(Rect(25, 15, 20, 60)), Scalar(255, 255, 255), -1); 177 | floodFill(mask, Point(0, 0), Scalar(255)); 178 | //Mat im_th; 179 | //threshold(im_in, im_th, 220, 255, THRESH_BINARY_INV); 180 | 181 | //// Floodfill from point (0, 0) 182 | //Mat im_floodfill = im_th.clone(); 183 | //floodFill(im_floodfill, cv::Point(0, 0), Scalar(255)); 184 | 185 | //// Invert floodfilled image 186 | //Mat im_floodfill_inv; 187 | //bitwise_not(im_floodfill, im_floodfill_inv); 188 | //Mat im_out = (im_th | im_floodfill_inv); 189 | //imshow("imout", im_out); 190 | //waitKey(); 191 | 192 | 193 | 194 | imwrite("./Mask/slotf" + std::to_string(i) + ".png", cropped); 195 | imwrite("./Mask/slot" + std::to_string(i) + ".png", mask); 196 | std::cout << " SLOT " << i + 1 << color << "\n"; 197 | //bitwise_and(cropped, cropped, cropped, mask); 198 | copyTo(mask, cropped, noArray()); 199 | //imshow("cropped", cropped); 200 | //waitKey(); 201 | if (color[0] > 100) { 202 | std::cout << "\n" << "Testing Slot " << i + 1 << "\n"; 203 | for (int i = 0; i < 13; i++) { 204 | similiarityCount = 0; 205 | scene = imread("./Mask/" + std::to_string(i) + ".png", IMREAD_GRAYSCALE); 206 | resize(scene, scene, Size(), 270.0 / scene.cols, 270.0 / scene.rows); 207 | Ptr detector; 208 | detector = FastFeatureDetector::create(); 209 | detector->detect(scene, keypoints_scene); 210 | detector->detect(cropped, keypoints_obj); 211 | 212 | //SIFT FEATURE EXTRACTION 213 | Ptr extractor = SIFT::create(); 214 | extractor->compute(scene, keypoints_scene, descriptors_sence); 215 | extractor->compute(cropped, keypoints_obj, descriptors_box); 216 | 217 | 218 | //BRUTE FORCE FOR MATCHING 219 | double RATIO = 0.7; 220 | double thresholdDistance = RATIO * sqrt(double(scene.size().height * scene.size().height + scene.size().width * scene.size().width)); 221 | Ptr matcher = BFMatcher::create(); 222 | std::vector> matches; 223 | matcher->knnMatch(descriptors_sence, descriptors_box, matches, 50); 224 | std::vector good_matches; 225 | for (size_t i = 0; i < matches.size(); ++i) 226 | { 227 | for (int j = 0; j < matches[i].size(); j++) 228 | { 229 | Point2f from = keypoints_obj[matches[i][j].queryIdx].pt; 230 | Point2f to = keypoints_scene[matches[i][j].trainIdx].pt; 231 | 232 | //calculate local distance for each possible match 233 | double dist = sqrt((from.x - to.x) * (from.x - to.x) + (from.y - to.y) * (from.y - to.y)); 234 | if (matches[i][0].distance < RATIO * matches[i][1].distance) 235 | { 236 | good_matches.push_back(matches[i][j]); 237 | similiarityCount++; 238 | j = matches[i].size(); 239 | } 240 | } 241 | } 242 | //resultVector[i][1] = std::to_string(std::atoi(resultVector[i][1].c_str()) + similiarityCount 243 | //std::cout << "Similiarity: " << similiarityCount << "\n"; 244 | if (similiarityCount > highestSimilarity) { 245 | Mat img_matches; 246 | drawMatches(scene, keypoints_scene, cropped, keypoints_obj, good_matches, img_matches, Scalar::all(-1), 247 | Scalar::all(-1), std::vector(), DrawMatchesFlags::DEFAULT); 248 | highestSimilarity = similiarityCount; 249 | probablyIndex = i; 250 | copyTo(img_matches, savedResult, noArray()); 251 | std::cout << "Similiarity: " << similiarityCount << "\n"; 252 | imshow("Good Matches", img_matches); 253 | waitKey(); 254 | } 255 | //waitKey(0); 256 | //waitKey(); 257 | } 258 | printf("Took %dms\n", (int)std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - startIter).count()); 259 | //waitKey(); 260 | //imshow("./rslt.png", img); 261 | rectangle(img, Rect2i(Rect(start.x, start.y, mid_y - 5, mid_y - 5)), Scalar(0, 0, 255), 3); 262 | } 263 | else { 264 | rectangle(img, Rect2i(Rect(start.x, start.y, mid_y - 5, mid_y - 5)), Scalar(255, 0, 0), 3); 265 | } 266 | //line(img, Point(start.x, start.y), Point(scanThis.x + 10, scanThis.y), Scalar(0, 0, 255), 3); 267 | //circle(img, Point(start.x + 30, start.y + 40), 10, Scalar(255, 0, 0), 2); 268 | } 269 | imshow("img", savedResult); 270 | resize(img, img, Size(), 1920.0 / img.cols, 1080.0 / img.rows); 271 | imwrite("Screen.png", img); 272 | imshow("imgg", img); 273 | std::cout << weaponsIDX[probablyIndex].name << "Highest Similarity " << highestSimilarity << "\n"; 274 | printf("Took %dms\n", (int)std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start).count()); 275 | waitKey(); 276 | } 277 | 278 | 279 | --------------------------------------------------------------------------------