Вопрос или проблема
Я действительно стараюсь применить CLAHE к каталогу из примерно 700 изображений. Однако, как только мне удается запустить его, по какой-то причине код останавливается до того, как все изображения будут обработаны.
Когда я запускаю его в Google Colab, он останавливается на полпути (то есть на изображении № 355). Из-за отчаяния я скачал набор изображений на свой локальный компьютер и попытался запустить его в локальном блокноте Jupyter, но даже тогда он останавливается после 100 изображений. Что происходит?
Вот мой код:
import cv2 as cv
import shutil
import os
source = r"/All classes copy/0/"
destination = r"/temp dir/0/"
filelist = os.listdir(r"/All classes copy/0/")
clahe = cv.createCLAHE()
for x in filelist:
img = cv.imread(x,0)
cl1 = clahe.apply(img)
cv.imwrite(os.path.join(destination, x),cl1)
print(os.path.join(source, x), '>>>', os.path.join(destination, x))
filelist0.pop()
Вот ошибка, которая возникает только после того, как несколько сотен изображений были обработаны CLAHE:
---------------------------------------------------------------------------
error Traceback (most recent call last)
Input In [28], in <cell line: 11>()
12 img = cv.imread(x,0)
13 cl1 = clahe.apply(img)
---> 14 cv.imwrite(os.path.join(r"/temp dir/0/", x),cl1)
15 print(os.path.join(source, x), '>>>', os.path.join(destination, x))
16 filelist0.pop()
error: OpenCV(4.6.0) /Users/runner/work/opencv-python/opencv-python/opencv/modules/imgcodecs/src/loadsave.cpp:801: error: (-215:Assertion failed) !_img.empty() in function 'imwrite'
Тем не менее, я знаю, что эти изображения действительно существуют! В Colab обрабатывается больше изображений, чем локально. Это проблема стабильности с OpenCV? Или я исчерпал ОЗУ?
Я выяснил это. На самом деле, было несколько проблем, которые мешали этому коду выполняться без сбоев.
- Убедитесь, что вы находитесь в каталоге ‘source’, чтобы это работало, потому что первая строка кода (
img = cv.imread(x,0)
) не имеет явного пути, и таким образом ищет файлы в локальном каталоге с именем x - Убедитесь, что в исходном каталоге нет файлов, не являющихся изображениями
- Поскольку Colab иногда может казаться немного неустойчивым, может помочь создать новую (под другим именем) переменную
filelist
с каждым циклом (если вы делаете это в нескольких каталогах) - И, наконец, следуйте коду руководства до буквы! Я сначала разместил создание
clahe = cv.createCLAHE()
вне цикла, так как думал, что его нужно создать только один раз. Но это почему-то останавливает цикл раньше времени. Вы должны включить это в цикл, чтобы цикл выполнялся по всему исходному каталогу. Окончательный код будет таким:
import cv2 as cv
import shutil
import os
source = r'/content/drive/MyDrive/Colab Notebooks/All classes/0/'
destination = r'/content/drive/MyDrive/Colab Notebooks/CLAHE/0/'
filenames0 = os.listdir(r'/content/drive/MyDrive/Colab Notebooks/All classes/0/')
for x in filenames0:
img = cv.imread(x,0)
clahe = cv.createCLAHE()
cl1 = clahe.apply(img)
cv.imwrite(os.path.join(destination, x),cl1)
print(os.path.join(source, x), '>>>', os.path.join(destination, x))
```
Ответ или решение
При обработке изображений в OpenCV из директории возникают несколько распространённых проблем, которые можно исправить, чтобы код работал корректно и эффективно. Разберём основные ошибки и возможные решения, учитывая описанный сценарий и задачу применения алгоритма CLAHE к набору из 700 изображений.
-
Отсутствие полного пути при чтении изображений:
Проблема происходит из-за того, что функция
cv.imread()
вызывается без указания полного пути к файлу, что приводит к ошибке при обработке. Чтобы решить это, необходимо либо изменить рабочую директорию наsource
, либо использовать полный путь при вызовеcv.imread()
:img = cv.imread(os.path.join(source, x), 0)
-
Некорректное создание объекта CLAHE:
Раньше создание объекта CLAHE выполнялось вне цикла, что могло вызвать проблемы с постоянством объекта при большой нагрузке. Перемещение создания объекта внутри цикла позволяет избежать подобных сбоев:
for x in filelist: clahe = cv.createCLAHE() ...
-
Файлы, не являющиеся изображениями:
Убедитесь, что в исходной директории
source
нет файлов, которые не являются изображениями, т.к. это может вызвать ошибки чтения и записи. Можно игнорировать такие файлы следующим образом:if not x.endswith(('.png', '.jpg', '.jpeg', '.bmp', '.tiff')): continue
-
Проблемы с ресурсами (памятью):
Если обработка изображений всё равно замедляется из-за нехватки ресурсов, это может быть следствием работы с большим объёмом данных. Попробуйте обрабатывать изображения порциями, либо увеличьте лимиты выделяемой памяти, если это возможно на вашей платформе.
-
Инициализация переменной
filelist
и отсутствие необходимости вызоваfilelist.pop()
:В вашем цикле вызов метода
pop()
для списка не нужен. Это может создавать путаницу или потенциальные ошибки. Уберите этот код, чтобы избежать неясностей.
Заключительный исправленный код будет выглядеть следующим образом:
import cv2 as cv
import os
source = r'/path/to/source/directory/'
destination = r'/path/to/destination/directory/'
filelist = os.listdir(source)
for x in filelist:
if not x.endswith(('.png', '.jpg', '.jpeg', '.bmp', '.tiff')):
continue
img_path = os.path.join(source, x)
img = cv.imread(img_path, 0)
if img is None:
print(f"Could not read image {img_path}")
continue
clahe = cv.createCLAHE()
cl1 = clahe.apply(img)
destination_path = os.path.join(destination, x)
cv.imwrite(destination_path, cl1)
print(f"{img_path} >>> {destination_path}")
Стабильность выполнения зависит от конкретных условий использования и конфигурации окружения, поэтому регулярный мониторинг ресурсов и корректное управление ими остаются важными аспектами при работе с большими наборами данных.