Бывает такое, что вы точно знаете, что ваш скрипт рабочий, но он не работает? При последнем запуске все работало отлично, а сейчас он упал! Где искать причину и как это починить???
YOLO – одна из самым популярных архитектур для обнаружения объектов (object detection). Darknet — библиотека машинного обучения, написанная специально для YOLO на языке С/С++. Естественно она использует OpenCV для реализации массы полезных возможностей. Плюс ко всему, Darknet Yolo имеет хорошее API для работы с ней из-под Python. Всего-то нужно скомпилировать Darknet как SO-библиотеку, и воспользоваться прилагающимся darknet.py скриптом, описывающим его API для Python.
Процедура проста:
- компилируем Darknet
- запускаем python скрипт для обнаружения объектов.
Все так и было в моем случае, пока в какой-то момент, обновление исходного кода Darknet, и последующая его компиляция не стала приводить к ошибки сегментации:
Ошибка сегментации без явного указания на место сбоя и без трассировки — указывает на то, что вероятно, ошибка произошла в С-расширении. Первым предпринятым шагом было пройти дебаггером по коду в darknet_images.py.

При попытке импортировать OpenCV возникает ошибка сегментации. Это происходит только при выполнении данного скрипта, и не происходит при выполнении иного пользовательского кода. Причем, ранее рабочая версия Darknet, до обновления исходного кода работает нормально. Естественным желанием является удалить OpenCV из всех сред (в текущий момент использую conda virtual env), и скомпелировать заново. Забегая вперед — это поможет. Однако интересно, что сломалось, чтобы в будущем не допустить таких проблем. А кто сталкивался с компиляцией OpenCV, наверняка знает, что процесс этот не самый простой, особенно для новичка, а для знающего — это просто потерянный час-два времени.
Как у Вас организовано рабочее пространство? Если Вы Python разработчик, наверняка у Вас под каждый крупный проект настроена виртуальная среда. Если Вы не знаете, как это работает, или не используете такой подход, стоит обратить внимание на изолирование рабочих сред под проекты.
В настоящее время я использую менеджер пакетов conda и, соответственно, использую менеджер виртуальных сред conda (conda environments). В среде для работы с Darknet был установлен OpenCV с помощью pip, так как изначально использовалась реализация YOLOv3 на PyTorch. В это время в ходу был OpenCV 4.2.0.32. Когда я перешел на Darknet, эта версия OpenCV все еще была актуальна, но её я скомпилировал из исходников, а для виртуальной среды не стал её заменять. Прошло некоторое время и понадобился OpenCV скомпилированный с CUDA. Я удалил всё, что связано с текущей версией OpenCV, клонировал текущую версию и скомпилировал глобально. В виртуальной среде осталась та же 4.2.0.32, а глобально версия стала 4.4.0.42. Компиляция новой версии Darknet происходила с новой версией OpenCV. Данный конфликт версий и привел к ошибке сегментации. Простое обновление версии OpenCV до версии 4.4.х.х в виртуальной среде решило проблему. Причем, компилировать глобально с установкой в нужную среду не было необходимости, сработало обновление с помощью pip. Лучшее решени, вместо использования pip, вероятно, будет — создать символьную ссылку на OpenCV из
/usr/local/lib/python3.6/dist-packages/cv2/python-3.6/cv2.cpython-36m-x86_64-linux-gnu.so
в актуальную виртуальную среду:
$ cd ~/anaconda3/envs/env_name/lib/python3.8/site-packages/
$ ln -s /usr/local/lib/python3.6/dist-packages/cv2/python-3.6/cv2.cpython-36m-x86_64-linux-gnu.so cv2.so
Что делать? Создавать виртуальные среды для каждого крупного проекта. Возможно, создавать виртуальные среды для версий крупного проекта, если это оправдано. Если нет, обязательно следите, в каком месте происходит изменение и актуализируйте эти изменения для соответствующего рабочего пространства.
Что почитать: