Open s-trinh opened 2 weeks ago
Hello, That's weird I cannot reproduce your error using the same parameters. Could you please run the following:
$ cd $VISP_WS/visp-build/tutorial/image
$ ./tutorial-canny -i /tmp/img.png --ratio 0.6 1.5 --gradient 3 0.5 --aperture 3
On my computer (Ubuntu 22.04) the program works correctly (even if the Canny results are a bit odd due to the exposure of the image)
Yes I have the same issue with ./tutorial-canny -i /tmp/img.png --ratio 0.6 1.5 --gradient 3 0.5 --aperture 3
Increasing the stack size did not help:
ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 62389
max locked memory (kbytes, -l) 65536
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 62389
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
ulimit -s 16384
ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 62389
max locked memory (kbytes, -l) 65536
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 16384
cpu time (seconds, -t) unlimited
max user processes (-u) 62389
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
I suspect that the high threshold is too high, leading to all the edges being considered as weak edges. Due to that, the vpCannyEdgeDetection::recursiveSearchForStrongEdge
could be called until the stack of calls is too high to be handled. Could you please replace the code of this method by the following, compile and give me the result of the print please ? Basically, instead of calling vpCannyEdgeDetection::recursiveSearchForStrongEdge
, the method vpCannyEdgeDetection::performEdgeTracking
will count the number of weak and strong edges.
void
vpCannyEdgeDetection::performEdgeTracking()
{
std::map<std::pair<unsigned int, unsigned int>, EdgeType>::iterator it;
std::map<std::pair<unsigned int, unsigned int>, EdgeType>::iterator m_edgePointsCandidates_end = m_edgePointsCandidates.end();
unsigned int nbStrongEdges = 0, nbWeakEdges = 0;
for (it = m_edgePointsCandidates.begin(); it != m_edgePointsCandidates_end; ++it) {
if (it->second == STRONG_EDGE) {
m_edgeMap[it->first.first][it->first.second] = 255;
if (m_storeListEdgePoints) {
m_edgePointsList.push_back(vpImagePoint(it->first.first, it->first.second));
}
++nbStrongEdges;
}
else if (it->second == WEAK_EDGE) {
// if (recursiveSearchForStrongEdge(it->first)) {
m_edgeMap[it->first.first][it->first.second] = 255;
// }
++nbWeakEdges;
}
}
std::cout << "[vpCannyEdgeDetection::performEdgeTracking]#strong edges = " << nbStrongEdges << std::endl;
std::cout << "[vpCannyEdgeDetection::performEdgeTracking]#weak edges = " << nbWeakEdges << std::endl;
}
The output:
I_gray=1788x942
[vpCannyEdgeDetection::performEdgeTracking]#strong edges = 102138
[vpCannyEdgeDetection::performEdgeTracking]#weak edges = 539881
OK not what I expected to be honnest, I was expected something like 0 strong edges and a lot of weak edges. What's weird is that I cannot reproduce it, the Mac OS CIs worked but the Ubuntu 22.04 CIs failed.
The differences between our configurations:
By any chance do you have Docker ? If so, could you create an image based on Ubuntu 22.04 with the same c++ compiler version than I have to see if it changes anything ? It might not, because it seems that the OS release is different between the Docker images and the one that is installed on my computer.
Other question: have you ever faced this segfault with other images ? Such as a with an image with a gray empty square inside ? (it can be generated using vpImageDraw)
After a second thought, I will create a Docker that reproduces your configuration, try to reproduce the bug and come back to you if that's fine with you ?
OK I downloaded the image you posted (before I did a screenshot because I didn't find how to save it) and now I have a segfault on my computer too. So it's not due to a different configuration, there is a segfault happening somewhere. I'll continue to dig in.
Found the problem ! My original thought was correct, the problem came from the upper threshold ratio you used. It must be between 0 and 1, because it corresponds to the ratio of points that must have the norm of their gradient lower than the found threshold. In other words, if you set the upper ratio to 0.5, it means that at least 50% of the pixels will have a gradient lower than the found threshold.
See #1490 for the fix.
Thanks for your quick feedback. I also have to refresh the webpage sometimes in order to open the image in another tab on Github.
It looks like for certain values of Gaussian std and for some over-exposed images we are hitting somehow the limit of the stack size.
For instance when using this image or the image from the first post
./tutorial-canny -i /tmp/2015_03449.png --gradient 3 0.5
:Canny Configuration:
Filtering + gradient operators = gaussianblur+sobel-filtering
Gaussian filter kernel size = 3
Gaussian filter standard deviation = 0.500000
Gradient filter kernel size = 3
Canny edge filter thresholds = [-1.000000 ; -1.000000]
Canny edge filter thresholds ratio (for auto-thresholding) = [0.600000 ; 0.800000]
dIx_uchar
dIy_uchar
without the recursiveSearchForStrongEdge()
it gives:
[vpCannyEdgeDetection::performEdgeTracking]#strong edges = 77555
[vpCannyEdgeDetection::performEdgeTracking]#weak edges = 264432
recursiveSearchForStrongEdge()
hitting the stack size limit)It works correctly with ./tutorial-canny -i /tmp/2015_03449.png --gradient 3 0.1
.
Increasing the stack size make it works.
ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 62389
max locked memory (kbytes, -l) 65536
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 62389
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
ulimit -s 16384
ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 62389
max locked memory (kbytes, -l) 65536
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 16384
cpu time (seconds, -t) unlimited
max user processes (-u) 62389
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
./tutorial-canny -i /tmp/2015_03449.png --gradient 3 0.5
Canny Configuration:
Filtering + gradient operators = gaussianblur+sobel-filtering
Gaussian filter kernel size = 3
Gaussian filter standard deviation = 0.500000
Gradient filter kernel size = 3
Canny edge filter thresholds = [-1.000000 ; -1.000000]
Canny edge filter thresholds ratio (for auto-thresholding) = [0.600000 ; 0.800000]
And the result image:
This issue seems definitively due to the recursive algorithm. I remember that in vpDot that implements also a recursive algorithm, we had also issues with the size of the stack.
The fix that I found on that time was to add in vpDot.cpp.
#ifdef VISP_USE_MSVC
#pragma comment(linker, "/STACK:256000000") // Increase max recursion depth
#endif
Similar code could be tested to see if it helps.
@s-trinh oh indeed the results largely differ depending on the gradient standard deviation ! My bad, I tested the algorithm on some images coming from a dataset known for testing Canny implementations, but I didn't think to try it on overexposed images. I will try the solution proposed by @fspindle and let you know the results.
Hello,
With the following image, I encounter a segfault with ViSP
v3.6.0-1651-ga65eebc2f-dirty
.Code to reproduce the issue:
gdb stack trace:
Looks like using the following guard does not help: