{"id":20373163,"url":"https://github.com/st235/hse.2dimageprocessing.week3","last_synced_at":"2026-06-07T00:32:00.207Z","repository":{"id":140153774,"uuid":"568405783","full_name":"st235/HSE.2DImageProcessing.Week3","owner":"st235","description":null,"archived":false,"fork":false,"pushed_at":"2022-11-30T22:32:41.000Z","size":23279,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-04T20:43:57.728Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/st235.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-20T12:44:44.000Z","updated_at":"2022-11-20T23:10:59.000Z","dependencies_parsed_at":null,"dependency_job_id":"0e31c24c-5eb5-4269-b63e-30baa1715cac","html_url":"https://github.com/st235/HSE.2DImageProcessing.Week3","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/st235/HSE.2DImageProcessing.Week3","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/st235%2FHSE.2DImageProcessing.Week3","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/st235%2FHSE.2DImageProcessing.Week3/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/st235%2FHSE.2DImageProcessing.Week3/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/st235%2FHSE.2DImageProcessing.Week3/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/st235","download_url":"https://codeload.github.com/st235/HSE.2DImageProcessing.Week3/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/st235%2FHSE.2DImageProcessing.Week3/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34005030,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-06T02:00:07.033Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T01:16:56.709Z","updated_at":"2026-06-07T00:32:00.192Z","avatar_url":"https://github.com/st235.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# HSE.2DImageProcessing.Week3\n\nHello my fellow classmates 👋\n\nThank you for reading this introduction document! Hopefully, I would be able to keep you interested 😅\n\n## Build\n\nTo build the project you have to have [OpenCV installed](https://docs.opencv.org/4.x/d7/d9f/tutorial_linux_install.html) on your computer. \n\nWhen everything is ready you need to navigate to `src` folder in your terminal and execute the following chain of commands.\n\n```\nmkdir build\ncd build\n\ncmake ..\nmake -j7\n```\n\nThe build will be finished shortly after calling the command and you can expect to see the executable file inside `bin` directory. Hopefully, the file is there and you are ready to move to the next step!\n\n## Command\n\nGenerally, the application accepts a few command line arguments. If there was a _help_ command it would output something similar to the text below.\n\n```bash\n./bin/CoinDetector image1 image_folder1 image2 ... imageN [-o output prefix] [-c coins config] [-d debug] [-dc draw config coins]\n```\n\nHowever, it can be a bit confusing. Let me breifly explain what these arguments do. Basically, the invocation consists of two important groups: an images list and additional arguments.\n\n1. **Images list**: just a list of either image files or folders with images. If an entry is an images folder then all images are recursively extracted from within it.\n\n2. **Additional arguments**: all arguments are optional. If you decide to use them read thoroughly the infromation in the table below.\n\n|Argument|Desciption|\n|-----|-----|\n|-d| *Debug flag*: if specified then the application displays additional processing steps, otherwise only result image with detected coins will be shown. |\n|-o| *Output files prefix*: specifies the final directory for output images. If not specified then the final images will be saved in the application folder, ie the folder from where the application is located. |\n|-c| *Coins config file*: if specified then the passed images will be tested against this config and prediction metrics will be calculated. Config should contain information about coins in the given images. To create a custom config see [Config section](Config). |\n|-dc| *Draw config coins*: if specified coins from config will be displayed as **blue** circles on the final image. |\n\n### Usage example\n\nTo give you a better context on how to use the application I provided a few usage examples.\n\n- Folder with images + metrics config\n\n```base\n./bin/CoinsDetector ../../Samples -c ../../Samples/circles.txt\n```\n\n- Single image + metrics config\n\n```bash\n./bin/CoinsDetector ../../Samples/20.jpg -c ../../Samples/circles.txt\n```\n\n- Single image + debug flag\n\n```bash\n./bin/CoinsDetector ../../Samples/20.jpg -d\n```\n\n- Single image + metrics config + custom output prefix\n\n```bash\n./bin/CoinsDetector ../../Samples/19.jpg -c ../../Samples/circles.txt -o ../../Samples\n```\n\n## Config\n\nConfig describes the given images set. When the images set is tested against config all images from the set should be on the config, however, the config may have more images descriptors than the set has. If the image is not found on the set [runtime_error](https://en.cppreference.com/w/cpp/error/runtime_error) is rised.\n\nTo make your own config or understand better how the original config is composed you may find these set of rules quite useful:\n\n- Every image that you want to test should be described in the config;\n- Every image has its own descriptor/config section;\n- There should be an empty line between sections;\n- A section should distinctly identify the image using image id followed by a circles list;\n- *image id* is __image name__ + __image extension__, for examples, for the field `./a/b/image.png` the id is `image.png`;\n- Every circle is a triple of x and y coordinates and a radius.\n\nThese rules can be visualised in the following way:\n\n```text\nimage_id_1\nx1,y1,r1\nx2,y2,r2\nx3,y3,r3\n\nimage_id_2\nx1,y1,r1\n\n...\n\nimage_id_n\nx1,y1,r1\nx2,y2,r2\nxN,yN,rN\n```\n\nYou can see how these rules are applied looking at [the given config](./Samples/circles.txt):\n\n```text\n01.jpg\n185,180,66\n384,285,98\n609,204,111\n171,369,84\n343,478,58\n602,504,104\n169,608,81\n421,638,62\n\n02.jpg\n64,66,65\n185,55,43\n310,62,59\n56,186,54\n186,184,76\n313,187,53\n51,306,60\n142,310,39\n225,309,44\n320,302,50\n\n...\n```\n\n## Test Samples\n\nThere are 20 test sample images that form the test set. All coins in the set are are distinguihsable from background, well illuminated, and do not have extreme points views.\n\nTo give you a better understanding of the tests' nature you can see the example.\n\n![Example](./Samples/03.jpg)\n\nYou may take a look at the rest of the test set by looking at [the samples folder](./Samples/).\n\n## Algorithm\n\nThe algorithm used in the project is not that sophisticated and can be represented as a chain of several steps.\n\n*Note: To reproduce the same behaviour run the following command:*\n\n```bash\n./bin/CoinsDetector ../../Samples/13.jpg  -c ../../Samples/circles.txt -o ../../Images -d\n```\n\n| Step | Image  | Description  |\n| ------- | --- | --- |\n| 0. Original image | ![Original](./Samples/13.jpg) | Unmodified image. This is not an actual step. I put it here to show the original image. |\n| 1. Read the image | ![Grayscale](./Images/1.grayscale.png) | Converts the given image to grayscale. |\n| 2. Smoothing | ![Smoothing](./Images/2.smoothing.png) | Smooths the image using Sobel operator to reduce noise. |\n| 3. Edge detection | ![Canny](./Images/3.canny.png) | Canny algorithm to detect edges. |\n| 4. Thresholding | ![Thresholding](./Images/4.threshold.png) | Otsu thresholding to make a binary image. |\n| 5.1 Morphological: dilate |  | Agressive dilation to combine all edges into a single circle. |\n| 5.2 Morphological: open | ![Close](./Images/5.morphology.png) | Erosion to remove the noise and dilation to return the circles back to original sizes. |\n| 6. Contour | ![Contour](./Images/6.contour.png) | Contours detection to separate contours of circles and draw them with a given thickness. |\n| 7. Smoothing | ![Smoothing](./Images/7.smoothing.png) | Smoothing to reduce noise. |\n| 8.1 Morphological: close | ![Smoothing](./Images/8.close.png) | Dilation followed by errosion to merge for the last time all separated objects. |\n| 8.2 Morphological: open | ![Smoothing](./Images/9.open.png) | Errosion followed by dilation to reduce noise if left. |\n| 8.3 Morphological: dilate | ![Smoothing](./Images/10.dilate.png) | Dilation to make contours thicker. |\n| 9. Hough Circles | ![Hough Circles](./Images/11.result.png) | Hough circles transform to detect circles. |\n\n\n## Model Results\n\nAnd the most interesting part: the results part.\n\n*Note: To reproduce the same behaviour run the following command:*\n\n```text\n./bin/CoinsDetector ../../Samples -c ../../Samples/circles.txt\n```\n\nOverall there are __173 coins__ in the given test set. The metrics are:\n\n|Metric|Value|\n|---|---|\n|True positive|161|\n|True negative|0 **the value is expected as we don't have such a group in our dataset**|\n|False positive|12|\n|False negative|12|\n|Precission|0.930636|\n|Recall|0.930636|\n|F1 Score|0.930636|\n\n*As was agreed in the lecture, the model detects a few circles incorrectly and keeps the score below 100% perfect.*\n\nYou can also see a similar report in your terminal when you run the application using your own equipment.\n\nFinal report with the images is located in [Report/Samples folder](./Report/Samples/).\n\n### Detected circles example\n\nThis section just shows a few final result.\n\n| Sample 4 | Sample 9 | Sample 14 |\n| --- | --- | --- |\n| ![Detected Coins 4](./Images/detection.sample.3.jpg) | ![Detected Coins 9](./Images/detection.sample.1.jpg)| ![Detected Coins 14](Images/detection.sample.2.jpg) |\n\nAlso I attached the results of the coins from lectures\n\n| Sample 1 | Sample 2 |\n| --- | --- |\n| ![Lecture Sample 1](./Images/lecture.1.png) | ![Lecture Sample 2](./Images/lecture.2.png)|\n\n**Additional test images can be found in [Additional](./Additional/).**\n\n### Images where the model fails\n\nMy model fails to detect coins that are located on a noisy background (non-monochromatic) or with coins captured using extreme angles.\n\nSuch examples are given below:\n\n| Sample 2 | Sample 4 |\n| --- | --- |\n| ![Detected Coins 2](./Images/invalid_01.jpg)| ![Detected Coins 4](./Images/invalid_04.jpg) |\n\n\nWow, if you read this far you're a real hero. \n*Hopefully, you've enjoyed the reading the document. Thank you and good luck!*\n\n## License\n\n```text\nMIT License\n\nCopyright (c) 2022 Alex Dadukin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fst235%2Fhse.2dimageprocessing.week3","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fst235%2Fhse.2dimageprocessing.week3","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fst235%2Fhse.2dimageprocessing.week3/lists"}