alicevision / CCTag

Detection of CCTag markers made up of concentric circles.
https://cctag.readthedocs.io
Mozilla Public License 2.0
358 stars 89 forks source link

cctagDetection works well in ubuntu but failed in windows 10 #179

Closed MrIsland closed 2 years ago

MrIsland commented 2 years ago

Describe the problem When I move this application from ubuntu 18.04 to windows 10, the cctagDetection function shows an error as "Assertion failed". I checked that all inputs to this function are consistent with the ubuntu environment, and I didn't know where the wrong is. Look forward to your favourable help! Many thanks.

ps. I installed cctag by using cmd vcpkg. [vcpkg install cctag[apps]:x64-windows] opencv version : 3.4.16

Screenshots image

error info: image

simogasp commented 2 years ago

Is this a code that you wrote yourself? Can you try with one of the images in the sample folder here in the root of the project? You can also try to use the detection application of this repository (src/applications/detection) which vcpkg installs in the tools folder.

MrIsland commented 2 years ago

Thanks for your help! I tried both ways you mentioned, but still have problems. The detection application can run successfully both with the image in the sample folder and image of mine. However, for the first way, I rewrote a test script and replaced the image with the one you mentioned. It still failed in opencv.....

Below are my failed attempts. image

And the image img2 is the 01.png in the sample folder. Both src and graysrc can be displayed nicely with the imshow function.

simogasp commented 2 years ago

Sorry I don't have a pc at hand to test your code. The only difference wrt the code of the detection app is that it uses a different cctagDetection()function, as there are several overloaded functions with the same name but different input parameters. You can try to use the same just to be sure (you can forget about all the debug functions that are called before and after) and see if there is any difference.

MrIsland commented 2 years ago

I'm sorry for the late reply to you ! In fact, the code of test script comes from the library usage in the documentation on github. I previously thought that as long as the parameters passed in were the same as the sample program, the cctag would be detected without any problems. I went and looked up the cctagDetection() function, I found two in ICCTag.hpp , both of them lead to cctagDetection() in Detection.cpp. So after I try to these two overloaded functions, I failed again :).

It is worth mentioning that, the error comes from cvRecode.cpp in line 181, when i==1440 as the sample image's height is 1440. Emmmm, that's all. )YSJ@TE3XV0~H%UH%W)L4GE

Thank you for your continued answers~

simogasp commented 2 years ago

that's really strange. All the overload functions will give the same results, so at least it is good that it fails consistently. But it is strange that the error at line 181 is a out of bound kind of error, imgDX should be larger than the original image because of the filter2d() call a few lines above with the BORDER_REPLICATE option. Could you check the size of imgDX and imgSX?

MrIsland commented 2 years ago

I tried it. And the size of imgDx and imgDY are both 1920 x 1440. I'm sorry that I‘m not very familiar with the fileter2D() of opencv, so what should the size of imgDX be in principle after this step?

And I found some info in opencv 3.4.16 .It seems the output image should be the same size of original image? }_0(_VIXI4AXL R7H {B29T

Below are some of my attempts. image

simogasp commented 2 years ago

Oh yes my bad, the borders are treated internally and the return images have the same size. So that <= size.height in the for loop is wrong, should be only < but I wonder how it worked so far and for the detection application :thinking: :worried: Does it fail even when you build and run in Release mode?

MrIsland commented 2 years ago

Oh ! The answer is Release mode, as it can run successfully in that mode. It's my bad ignoring this.... Thanks for your patience and help!

simogasp commented 2 years ago

No, it's not your bad, there must be something wrong. In release mode all those error messages are simply disabled, which means it is potentially reading past the bounds of the images. So that's not the answer. So thank YOU! ;-)

@griwodz any idea about that <= size.height that reads one row past the image size?

griwodz commented 2 years ago

That code is quite old, I cannot remember touching it.

But I don't think that the <=size.height in cvRecode.cpp:178 is a problem. The map buffer is allocated with size (layers (width+2) (height+2)) in cvRecode.cpp:149.

The lines "const short* _imgDX = imgDX.ptr(i);" are just initializing a pointer that points outside plane boundaries, but it's only used in the if(<size.height) branch. The problem could be in lines 239+240 - but I don't think that's it because of the 1-pixel edge on all sides.

griwodz commented 2 years ago

Ah, now I get it. Lines 181 and 182 should happen inside the "if( i < size.height)" branch.

The code tells me that this must be a feature that is only switched on during debugging. Because as I wrote about: those "imgDX.ptr(i);" instructions should never, ever touch the memory.

And this is what I see in https://github.com/opencv/opencv/blob/4.x/modules/core/include/opencv2/core/mat.inl.hpp

inline
uchar* Mat::ptr(int y)
{
    CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
    return data + step.p[0] * y;
}

So it is throwing an assert although the CCTag programmers did actually know what they were doing. Because opencv2/core/mat.hpp is included in Debug mode, CV_DbgAssert is active, it checks the boundary and because that test fails, it crashes.

Although the CCTag code never touches the actual out-of-bounds data.

That explains why it works when Debug is off.

simogasp commented 2 years ago

yes we need to move the declaration inside the if and do a new one later on L243-244