Проблема с Pyspark UDF для получения дескрипторов с проблемой openCV - PullRequest
1 голос
/ 12 февраля 2020

Я начинаю с философии 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 ():

root
| - path_img: string (nullable = true)
| - img_vectorized: array (nullable = true)
| | - element: float (содержитNull = 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'

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

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

Спасибо.

1 Ответ

0 голосов
/ 13 февраля 2020

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

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

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...|
+--------------------+--------------------+
...