-
Notifications
You must be signed in to change notification settings - Fork 164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add example of canny edge detection algorithm #258
base: develop
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this contribution.
I've done quick review and made a few comments. LGTM.
example/canny.cpp
Outdated
//Example how to detect edges via Canny algorithm | ||
|
||
template <typename SrcView> | ||
void smoothing(const SrcView &src) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gaussian_blur
or gaussian_smoothing
wouldn't be a clearer name?
It is an example with learning as primary purpose, isn't it.
example/canny.cpp
Outdated
for (int i = 1; i < dst.height() - 1; ++i) { | ||
for (int j = 1; j < dst.width() - 1; ++j, ++dst_loc.x()) { | ||
if (dst_loc(0, 0) == 150) { | ||
if (dst_loc(-1, -1) == 255 || dst_loc(-1, 0) == 255 || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, add comment explaining where do the 150
and 255
come from.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Antropovi This looks very good! Just a couple of minor comments.
example/canny.cpp
Outdated
using namespace boost::gil; | ||
|
||
// TOP_VALUE - value of strong edge pixel | ||
#define TOP_VALUE 255 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, avoid macros and prefer C++ qualities like const
, constexpr
.
example/canny.cpp
Outdated
using namespace std; | ||
using namespace boost::gil; | ||
|
||
// TOP_VALUE - value of strong edge pixel |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to repeat constant name
For complete records and references, here is @Antropovi confirmation this is intended as competency test: https://lists.boost.org/Archives/boost/2019/03/245630.php
|
I believe there is a bug in the last hysteresis step: it will only detect Г shaped edges, and not horizontally flipped L shaped edges. Let me give an example (the values are somewhere in the image padded by zeroes on all sides, the values are intensity of the pixel's luminosity): Case which current code will detect:
Case which current code will not detect
Here are the lines of code which are connected to the issues:
Instead, I believe there should be connected components search. The search process basically tries to hop over weak edge or strong edge and reach all of the reachable pixels from start location. If there is at least one strong pixel in the connected component, all should be marked as strong too. Could you please verify if my theory is correct? I believe a good input image for this test case should be one of the O shaped Unicode characters with upper diagonal part blurred out. |
This isn't a bug and there are some reasons, why I chose this implementation. |
Sorry for choosing confusing wording. I meant that weak edges that should've been included in the output will not be included. Thanks for clarification on the decisions. |
@Antropovi Thank you very much again for your example and explanation. I'd like to incorporate it into GIL's collection in |
@stefanseefeld Shall we add those as they are (optionally, with minor stylistic refactoring) to OTOH, perhaps this could be reworked as a library feature, a callable algorithm, not just an example. Any takers? |
With boost 1.80.0 and -std=c++20 I get the following compile errors:
All of which are trivially fixed. It would be nice if example code did not contain compile errors. |
@Bockeman it would be nice if you made it clear that your comment relates to this particular PR in any way. Otherwise, it would be nice if you posted it to discussion thread or report a bug or it would be even nicer if you could submit PR with the trivial fixes. Thanks in advance. |
@mloskot Thanks for taking notice! My comment above relates to the example/canny.cpp code, the only one in the "files changed" tab above. Here are my trivial fixes:
my fix:
my fix:
my fix:
my fix:
my fix:
Thanks @Antropovi for contributing this code. It works well for me and saved me a lot of time and effort in painstakingly constucting such from scratch. |
PR = Pull Request
I see. Well, this PR is a proposal and it has not been accepted and merged into the GIL sources. So it should be considered as a work in progress.
If you have an improved version of this example here, then please, feel free to contribute it to GIL and submit your version as new PR. |
Add example of canny edge detection using gil as my competency test for GSoC 2019
References
Find more about Canny edge detection on https://en.wikipedia.org/wiki/Canny_edge_detector
Tasklist
All CI builds and checks have passedATM, examples are not built by CI jobs