OpenCV не обрабатывает все изображения в каталоге.

Вопрос или проблема

Я действительно стараюсь применить 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? Или я исчерпал ОЗУ?

Я выяснил это. На самом деле, было несколько проблем, которые мешали этому коду выполняться без сбоев.

  1. Убедитесь, что вы находитесь в каталоге ‘source’, чтобы это работало, потому что первая строка кода (img = cv.imread(x,0)) не имеет явного пути, и таким образом ищет файлы в локальном каталоге с именем x
  2. Убедитесь, что в исходном каталоге нет файлов, не являющихся изображениями
  3. Поскольку Colab иногда может казаться немного неустойчивым, может помочь создать новую (под другим именем) переменную filelist с каждым циклом (если вы делаете это в нескольких каталогах)
  4. И, наконец, следуйте коду руководства до буквы! Я сначала разместил создание 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 изображений.

  1. Отсутствие полного пути при чтении изображений:

    Проблема происходит из-за того, что функция cv.imread() вызывается без указания полного пути к файлу, что приводит к ошибке при обработке. Чтобы решить это, необходимо либо изменить рабочую директорию на source, либо использовать полный путь при вызове cv.imread():

    img = cv.imread(os.path.join(source, x), 0)
  2. Некорректное создание объекта CLAHE:

    Раньше создание объекта CLAHE выполнялось вне цикла, что могло вызвать проблемы с постоянством объекта при большой нагрузке. Перемещение создания объекта внутри цикла позволяет избежать подобных сбоев:

    for x in filelist:
       clahe = cv.createCLAHE()
       ...
  3. Файлы, не являющиеся изображениями:

    Убедитесь, что в исходной директории source нет файлов, которые не являются изображениями, т.к. это может вызвать ошибки чтения и записи. Можно игнорировать такие файлы следующим образом:

    if not x.endswith(('.png', '.jpg', '.jpeg', '.bmp', '.tiff')):
       continue
  4. Проблемы с ресурсами (памятью):

    Если обработка изображений всё равно замедляется из-за нехватки ресурсов, это может быть следствием работы с большим объёмом данных. Попробуйте обрабатывать изображения порциями, либо увеличьте лимиты выделяемой памяти, если это возможно на вашей платформе.

  5. Инициализация переменной 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}")

Стабильность выполнения зависит от конкретных условий использования и конфигурации окружения, поэтому регулярный мониторинг ресурсов и корректное управление ими остаются важными аспектами при работе с большими наборами данных.

Оцените материал
Добавить комментарий

Капча загружается...