Сбои в тесте OpenCV 3 на NVIDIA Jetson TX2 (связано с gcc-7 против gcc < 7)

Я построил OpenCV 3.3.1 с OpenCV_Extra на Jetson TX2, как показано ниже, с отключенной CUDA:

cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_PNG=OFF -DBUILD_TIFF=OFF -DBUILD_TBB=OFF -DBUILD_JPEG=OFF -DBUILD_JASPER=OFF -DBUILD_ZLIB=OFF -DBUILD_EXAMPLES=ON -DBUILD_opencv_java=OFF -DBUILD_opencv_python2=ON -DBUILD_opencv_python3=ON -DENABLE_PRECOMPILED_HEADERS=OFF -DWITH_CUDA=OFF -DWITH_OPENCL=OFF -DWITH_OPENMP=OFF -DWITH_FFMPEG=ON -DWITH_GSTREAMER=OFF -DWITH_GSTREAMER_0_10=OFF -DWITH_GTK=ON -DWITH_VTK=OFF -DWITH_TBB=ON -DWITH_1394=OFF -DWITH_OPENEXR=OFF -DINSTALL_C_EXAMPLES=ON -DINSTALL_TESTS=ON -DCPACK_GENERATOR_DEB=ON -DOPENCV_TEST_DATA_PATH=../opencv_extra/testdata ../opencv

И запустил тестовый скрипт OpenCV, и обнаружил две ошибки теста в тестах 'Calib3d_Affine3f.accuracy' и 'match_bestOf2Nearest.bestOf2Nearest', как показано ниже:

[opencv_test_calib3d] RUN : /usr/bin/opencv_test_calib3d --perf_min_samples=1 --perf_force_samples=1 --gtest_output=xml:opencv_test_calib3d.xml
[opencv_test_calib3d] CTEST_FULL_OUTPUT
[opencv_test_calib3d] OpenCV version: 3.3.1
[opencv_test_calib3d] OpenCV VCS version: 3.3.1
[opencv_test_calib3d] Build type: release
[opencv_test_calib3d] Parallel framework: tbb
[opencv_test_calib3d] CPU features: neon fp16

[opencv_test_calib3d] [ RUN      ] Calib3d_Affine3f.accuracy
[opencv_test_calib3d] /home/nvidia/build-opencv/opencv/modules/calib3d/test/test_affine3.cpp:57: Failure
[opencv_test_calib3d]       Expected: 0
[opencv_test_calib3d] To be equal to: cvtest::norm(cv::Mat(affine.matrix, false).colRange(0, 3).rowRange(0, 3) != expected, cv::NORM_L2)
[opencv_test_calib3d]       Which is: 441.673
[opencv_test_calib3d] [  FAILED  ] Calib3d_Affine3f.accuracy (0 ms)

[opencv_perf_stitching] RUN : /usr/bin/opencv_perf_stitching --perf_min_samples=1 --perf_force_samples=1 --gtest_output=xml:opencv_perf_stitching.xml
[opencv_perf_stitching] Time compensation is 0
[opencv_perf_stitching] CTEST_FULL_OUTPUT
[opencv_perf_stitching] OpenCV version: 3.3.1
[opencv_perf_stitching] OpenCV VCS version: 3.3.1
[opencv_perf_stitching] Build type: release
[opencv_perf_stitching] Parallel framework: tbb
[opencv_perf_stitching] CPU features: neon fp16

[opencv_perf_stitching] [----------] 1 test from match_bestOf2Nearest
[opencv_perf_stitching] [ RUN      ] match_bestOf2Nearest.bestOf2Nearest/0
[opencv_perf_stitching]  Expected: 
[opencv_perf_stitching] [0.9970975582816909, 0.01136054503288174;
[opencv_perf_stitching]  -0.002557125266879237, 1.02781673911756;
[opencv_perf_stitching]  0.0002463026627945361, -1.679576661348132e-05]
[opencv_perf_stitching]  Actual:
[opencv_perf_stitching] [0.9986402872172184, -0.01796581492545124;
[opencv_perf_stitching]  -0.00230781842425846, 1.031312571169278;
[opencv_perf_stitching]  0.0002375978666932171, 9.189439617496881e-05]
[opencv_perf_stitching] /home/nvidia/build-opencv/opencv/modules/ts/src/ts_perf.cpp:571: Failure
[opencv_perf_stitching] Failed
[opencv_perf_stitching]   Difference (=0.029326359958332979) between argument1 "R" and expected value is greater than 0.014999999999999999
[opencv_perf_stitching] params    =       "orb"
[opencv_perf_stitching] termination reason:  reached maximum number of iterations
[opencv_perf_stitching] bytesIn   =      96896
[opencv_perf_stitching] bytesOut  =          0
[opencv_perf_stitching] samples   =          1
[opencv_perf_stitching] outliers  =          0
[opencv_perf_stitching] frequency = 1000000000
[opencv_perf_stitching] min       =  306334005 = 306.33ms
[opencv_perf_stitching] median    =  306334005 = 306.33ms
[opencv_perf_stitching] gmean     =  306334005 = 306.33ms
[opencv_perf_stitching] gstddev   = 0.00000000 = 0.00ms for 97% dispersion interval
[opencv_perf_stitching] mean      =  306334005 = 306.33ms
[opencv_perf_stitching] stddev    =          0 = 0.00ms
[opencv_perf_stitching] [  FAILED  ] match_bestOf2Nearest.bestOf2Nearest/0, where GetParam() = "orb" (577 ms)
[opencv_perf_stitching] [----------] 1 test from match_bestOf2Nearest (577 ms total)

Я пробовал как образ на основе Ubuntu 16.04, так и образ на основе Ubuntu 18.04 с разными версиями GCC. И ниже приводится краткое изложение моих выводов:

  • Сбой теста OpenCV на Calib3d_Affine3f.accuracy наблюдался на разных платформах с разными изображениями всякий раз, когда цепочка инструментов основана на gcc-7. И в любой комбинации платформа + образ этот тест всегда проходит, когда используется gcc < 7 (т. Е. Ниже, чем версия 7, например, gcc-6.4.0).

  • Неудачный тест OpenCV на match_bestOf2Nearest.bestOf2Nearest постоянно наблюдался независимо от того, какое изображение и какую версию gcc использовал.

Мое наблюдение состоит в том, что ошибка в тесте 'Calib3d_Affine3f.accuracy' вызвана тем, что сценарий теста сравнивает ожидаемые и фактические значения со знаком равенства (то есть ==), то есть сравнивает точные значения, не предполагая каких-либо изменений в плавающем точечные операции на разных платформах с разными компиляторами. При gcc <7 тест сравнения с плавающей точкой проходит успешно, но с gcc-7 он не проходит из-за того, что два значения с плавающей точкой немного отличаются, как 1e-17.

Вопросы:

  • Соответствует ли спецификация IEEE с плавающей точкой различным архитектурам в отношении точности?
  • Будет ли метод сравнения в тестовом сценарии OpenCV (т. Е. Точное сравнение значений вместо сравнения с допустимым пределом) типичным для значений с плавающей запятой согласно спецификации IEEE?
  • Почему поведение точности с плавающей точкой будет отличаться при использовании gcc-7 по сравнению с gcc < 7?
  • Как сделать тест пройденным с gcc-7 и двигаться вперед?

Второй случай сбоя в match_bestOf2Nearest.bestOf2Nearest также связан с точностью обработки в операции с плавающей запятой в некоторых функциях OpenCV. Я обнаружил, что функции OpenCV иногда приводят значения между CV_32F и CV_64F внутри. Если предположить, что формата CV_32F достаточно для обеспечения точности, это не должно иметь значения. В этом случае тестовый скрипт сравнивает ожидаемые и фактические значения с допустимым запасом, например, с эпсилоном (вместо точного тестирования на равенство значений). Наблюдение состоит в том, что тест завершается неудачно в зависимости от случайного начального числа, предоставленного в функциях, подразумевая, что предопределенный эпсилон недостаточно велик, или что операции с плавающей запятой на нашем ЦП имеют изменчивость, большую, чем предполагается в сценарии тестирования OpenCV.

Вопрос:

  • Будет ли что-нибудь связанное с особенностями архитектуры процессора на Jetson-TX2? Что бы это было?
  • Как решить эту проблему?

Было бы замечательно, если бы вы могли поделиться со мной своей мудростью!

0 ответов

Другие вопросы по тегам