Проблема с Pyspark UDF для получения дескрипторов с проблемой openCV

Я начинаю с философии Spark и, в моем случае, с Pyspark.

У меня есть небольшой школьный проект, который не кажется сложным, но я работаю над ним много дней и до сих пор не могу добиться успеха.

Мне нужно загрузить изображения в папку и извлечь дескрипторы, чтобы уменьшить размер.

Я создал фрейм данных Pyspark с путями к изображениям, и теперь я хотел бы добавить столбец с дескрипторами.

Вот как я это сделал.

Список путей к изображениям:

    lst_path = []

    sub_folders = os.listdir(folder)

    print(sub_folders)
    for f in sub_folders[:1]:

        lst_categ = os.listdir(folder + f)

        for file in lst_categ:

            lst_path.append(folder + f + "/" + file)

    print("Nombre d'images chargées :", len(lst_path))

    rdd = sc.parallelize(lst_path)
    row_rdd = rdd.map(lambda x: Row(x))
    df = spark.createDataFrame(row_rdd, ["path_img"])

Функция для извлечения дескрипторов:

def get_desc(img):

    img = cv2.imread(file)
    orb = cv2.ORB_create(nfeatures=50)
    keypoints_orb, desc = orb.detectAndCompute(img, None)

    desc = desc.flatten()

    return desc

Функция UDF:

udf_image = udf(lambda img: get_desc(img), ArrayType(FloatType()))

Создание новой колонки:

df2 = df.withColumn("img_vectorized", udf_image("path_img"))

Результат с printSchema ():

корень
| - path_img: string (nullable = true)
| - img_vectorized: array (nullable = true)
| | - элемент: float (containsNull = true)

И когда я делаю df2.show (), у меня появляется следующее сообщение об ошибке:

Py4JJavaError: ошибка при вызове o773.showString. : org.apache.spark.SparkException: задание прервано из-за сбоя этапа: задача 0 на этапе 18.0 не удалась 1 раз, последний сбой: потерянная задача 0.0 на этапе 18.0 (TID 93, localhost, драйвер-исполнитель): net.razorvine.pickle .PickleException: ожидаемые нулевые аргументы для построения ClassDict (для numpy.core.multiarray._reconstruct)

AttributeError: объект 'NoneType' не имеет атрибута 'flatten'

Замечу, что дескрипторы нулевые. Уточняю, когда я делаю это извлечение в одну строку, это работает.

Я не понимаю, почему это не работает с моим фреймворком данных. Не могли бы вы мне помочь?

Спасибо.


person Julien Di Giulio    schedule 12.02.2020    source источник


Ответы (1)


Я нашел решение вчера вечером после многих дней исследований ...

Мой исправленный код:

def get_desc(img):

    image = cv2.imread(img)
    orb = cv2.ORB_create(nfeatures=50)
    keypoints_orb, desc = orb.detectAndCompute(image, None)

    if desc is None:

        desc = 0
    else:
        desc = desc.flatten().tolist()

    return desc

udf_image = udf(get_desc, ArrayType(IntegerType()))

df_desc = df.withColumn("descriptors", udf_image("path_img"))

df_desc = df_desc.filter(df_desc.descriptors. isNotNull())

df_desc.show()
+--------------------+--------------------+ 
|            path_img|         descriptors|
+--------------------+--------------------+ 
|Training/Apple-Br...|[69, 113, 253, 10...| 
|Training/Apple-Br...|[212, 236, 159, 2...|
|Training/Apple-Br...|[60, 53, 123, 239...|
|Training/Apple-Br...|[255, 189, 252, 1...|
|Training/Apple-Br...|[204, 244, 149, 1...|
+--------------------+--------------------+
person Julien Di Giulio    schedule 13.02.2020