opencv_contrib
opencv_contrib copied to clipboard
We chat QR Scan crashes with certain images.
System information (version)
- OpenCV => 4.5.4
- Operating System / Platform => Ubuntu 20.04
- Compiler => Visual Studio Code 1.63.2
Detailed description
I've implemented the WeChat QR Code Scanner in a similar fashion to the one included in guides such as this one and this one (C++ implementations). The QR scanner seems to work in general, but we have noticed occasions where the process just crashes silently. After launching the script in debugging mod we have cached the following errors:
Object "/usr/local/lib/libopencv_wechat_qrcode.so.4.5", at 0x7fae230675ca, in cv::wechat_qrcode::WeChatQRCode::detectAndDecode[abi:cxx11](cv::_InputArray const&, cv::_OutputArray const&)
Object "/usr/local/lib/libopencv_wechat_qrcode.so.4.5", at 0x7fae23066fdb, in cv::wechat_qrcode::WeChatQRCode::Impl::decode[abi:cxx11](cv::Mat const&, std::vector<cv::Mat, std::allocator<cv::Mat> >&, std::vector<cv::Mat, std::allocator<cv::Mat> >&)
Thread 1 "qr_scan" received signal SIGSEGV, Segmentation fault. 0x00007ffff7cc1097 in zxing::qrcode::Detector::sizeOfBlackWhiteBlackRun(int, int, int, int) () from target:/usr/local/lib/libopencv_wechat_qrcode.so.4.5
Steps to reproduce
For reproducing, you can use the scanner method detectAndDecode
with the following image. We have found that this image manages to crash the scanner:
i have the same experience some image which crashing in one version such as opencv 4.5.5 => does not crash in other version 4.5.2 and same code dont crash under windows but crash in linux compile.
in my opinion opencv build options matter here
Thread 1 received signal SIGSEGV, Segmentation fault.
0x00007ffff52a150d in zxing::qrcode::Detector::sizeOfBlackWhiteBlackRun(int, int, int, int) () from /usr/local/lib/libopencv_wechat_qrcode.so.4.5
(gdb) where
#0 0x00007ffff52a150d in zxing::qrcode::Detector::sizeOfBlackWhiteBlackRun(int, int, int, int) () at /usr/local/lib/libopencv_wechat_qrcode.so.4.5
#1 0x00007ffff52a165f in zxing::qrcode::Detector::sizeOfBlackWhiteBlackRunBothWays(int, int, int, int, int, bool) () at /usr/local/lib/libopencv_wechat_qrcode.so.4.5
#2 0x00007ffff52a194a in zxing::qrcode::Detector::calculateModuleSizeOneWay(zxing::Refzxing::ResultPoint, zxing::Refzxing::ResultPoint, int, int) ()
at /usr/local/lib/libopencv_wechat_qrcode.so.4.5
#3 0x00007ffff52a5257 in zxing::qrcode::Detector::processFinderPatternInfo(zxing::Refzxing::qrcode::FinderPatternInfo, zxing::ErrorHandler&) ()
at /usr/local/lib/libopencv_wechat_qrcode.so.4.5
#4 0x00007ffff52a75f6 in zxing::qrcode::Detector::getPossibleAlignmentCount(int) () at /usr/local/lib/libopencv_wechat_qrcode.so.4.5
#5 0x00007ffff52b9212 in zxing::qrcode::QRCodeReader::decodeMore(zxing::Refzxing::BinaryBitmap, zxing::Refzxing::BitMatrix, zxing::DecodeHints, zxing::ErrorHandler&) ()
at /usr/local/lib/libopencv_wechat_qrcode.so.4.5
#6 0x00007ffff52bbda1 in zxing::qrcode::QRCodeReader::decode(zxing::Refzxing::BinaryBitmap, zxing::DecodeHints) () at /usr/local/lib/libopencv_wechat_qrcode.so.4.5
#7 0x00007ffff527ab14 in cv::wechat_qrcode::DecoderMgr::Decode(zxing::Refzxing::BinaryBitmap, zxing::DecodeHints) () at /usr/local/lib/libopencv_wechat_qrcode.so.4.5
#8 0x00007ffff527acb4 in cv::wechat_qrcode::DecoderMgr::TryDecode(zxing::Refzxing::LuminanceSource, zxing::Refzxing::Result&) () at /usr/local/lib/libopencv_wechat_qrcode.so.4.5
#9 0x00007ffff527b167 in cv::wechat_qrcode::DecoderMgr::decodeImage(cv::Mat, bool, std::__cxx11::basic_string<char, std::char_traits
FYI if you compile opencv just without any other options like below, without TBB without openGL etc... it works for me, crashing images works normal
cmake -D CMAKE_BUILD_TYPE=RELEASE
-D CMAKE_INSTALL_PREFIX=/usr/local
-DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib-4.5.2/modules
../opencv-4.5.2
Thank you for the advice, it could be a temporary workaround, however we need to compile several flags for our applications.
/cc @dddzg
Just in order to let you know, these are the flags we are using. Version is 4.5.4 as I've stated before.
# ------------------------------
&& cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D WITH_CUDA=ON \
-D WITH_CUBLAS=ON \
-D CUDA_FAST_MATH=1 \
-D WITH_GSTREAMER=ON \
-D WITH_OPENGL=ON \
-D CUDA_ARCH_BIN=${ARCH_BIN} \
-D CUDA_ARCH_PTX="" \
-D CUDA_NVCC_FLAGS="--expt-relaxed-constexpr" \
-D BUILD_opencv_cudacodec=ON \
-D WITH_V4L=ON \
-D WITH_TBB=ON \
-D ENABLE_FAST_MATH=1 \
-D WITH_QT=OFF \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D INSTALL_C_EXAMPLES=OFF \
-D INSTALL_PYTHON_EXAMPLES=OFF \
-D OPENCV_GENERATE_PKGCONFIG=ON \
-D OPENCV_EXTRA_MODULES_PATH=~/opencv_build/opencv_contrib/modules \
-D BUILD_EXAMPLES=OFF .. \
@alalek I managed to reproduce this crash is on my dev machine. Using the latest git commit from https://github.com/opencv/opencv/commit/b2e20a82ba27615a2e55325ed973d3e5ee5b6778 and https://github.com/opencv/opencv_contrib/commit/3b5a55876fe0502418a9d9fb7d388c40f2a626b1 the demo crashes immediately if compiled with -DENABLE_FAST_MATH=ON
. Pretty much any image you try will reproduce the crash.
I was able to reproduce the issue with current 4.x (pre-4.8.0) with Fast Math option enabled in debug mode only. Release works well. Stack is corrupted:
Thread 1 "test" received signal SIGSEGV, Segmentation fault.
0x00007ffff7b55997 in zxing::BitMatrix::get (this=0x555555d4c280, x=-2147483648, y=115) at /home/alexander/Projects/OpenCV/opencv_contrib/modules/wechat_qrcode/src/zxing/common/bitmatrix.hpp:56
56 unsigned char get(int x, int y) const { return bits[width * y + x]; }
and the proposed patch with Nans does not fix it, but hides something else.
With fast-math option compiler expects that floats could not be NaNs and makes related optimizations. Discussion on stackoverflow: https://stackoverflow.com/questions/69463347/why-does-gcc-ffast-math-disable-the-correct-result-of-isnan-and-isinf GCC issue: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84949 It looks like the right way to fix the Zxing library is not to return nan in detector.cpp:495, but return dedicated boolean status. IsNan is not needed any more. Other trials to handle nans with -fast-math will lead to sparadic issues that are compiler dependant.
To avoid SIGSEGV
need to add checks for input values in methods which access arrays (like Detector::sizeOfBlackWhiteBlackRun
, check for points inside of image rectangle)