Как преобразовать изображение ArrayFire в изображение Julia?

Я хочу использовать функции построения графика Plots.jl с изображением, загруженным с помощью функции load_image() ArrayFire.

Что у меня есть:

AFArray: 1000×300×3 Array{Float32,3}

Я хочу:

300×1000 Array{RGB{Any},2} with eltype RGB

Я не смог найти прямое преобразование в документации. Есть ли эффективный способ сделать это?


person atachsin    schedule 19.10.2020    source источник


Ответы (1)


Я не знаю конкретно о массивах ArrayFire, но в целом вы можете использовать reinterpret для таких операций. Если вы хотите, чтобы новый массив находился на процессоре, скопируйте его.

Тогда, в идеале, вы могли бы просто сделать

rgb = reinterpret(RGB{Float32}, A)

К сожалению, MxNx3 не является оптимальным расположением для массивов RGB, поскольку вы хотите, чтобы 3 значения располагались последовательно. Таким образом, вы должны либо убедиться, что массив имеет 3xMxN-разметку, либо вы можете сделать permutedims(A, (3, 1, 2)).

Наконец, чтобы получить матрицу, вы должны отбросить ведущее одноэлементное измерение, иначе вы получите массив размером 1xMxN.

So,

rgb = dropdims(reinterpret(RGB{Float32}, permutedims(A, (3, 1, 2))); dims=1)

Я предположил, что вы действительно хотите RGB{Float32} вместо RGB{Any}.

Кстати, я не уверен, как это будет работать, если вы хотите сохранить окончательный массив на графическом процессоре.

Редактировать: вы можете выбрать reshape вместо dropdims, на моем компьютере это кажется немного быстрее.

person DNF    schedule 19.10.2020
comment
спасибо за ваш ответ, сэр, но это занимает почти целую минуту на моем графическом процессоре, который использует 40% своей мощности для одного 100-килобайтного jpg, где решающей частью моей программы является скорость. Кроме того, каналы RGB без необходимости масштабируются до 255, и все, что я вижу на экране, — белое. Я хочу сказать, что моя основная причина использования Plots заключается в том, чтобы использовать его метки и оси, читая файлы непосредственно в GPU, мой код стал в 3 раза быстрее, должен ли я продолжать пробовать функцию переинтерпретации, или есть ли лучший способ рисовать оси на изображении с галочками и метками? - person atachsin; 19.10.2020
comment
На моем компьютере dropdims(reinterpret(RGB{Float32}, permutedims(A, (3, 1, 2))); dims=1) требуется ‹700 микросекунд для массива 1000x300x3 и всего 300 наносекунд для массива 3x1000x300. Поэтому я предполагаю, что это должно быть общение с графическим процессором, которое требует времени. Как выглядит ваш код? Пропустить GPU было бы быстрее. Что касается насыщенности, 0 — это черный, а 1 — белый, поэтому все должно масштабироваться внутри этого интервала. - person DNF; 19.10.2020
comment
это интересно, у меня есть функция под названием createBigFrame, которая объединяет 30 изображений в одно с функцией load_image внутри, которая дает мне AFArray: 1000×300×3 Array{Float32,3} за 0,03 секунды, после этого я запустил ваш код в отдельном блоке, и это заняло 76 секунд - person atachsin; 20.10.2020
comment
Да, я предполагаю, что связь между процессором и графическим процессором требует времени. Я не эксперт по Images.jl, но я не знаю, можно ли использовать массивы RGB на графическом процессоре. В этом случае, если вы действительно хотите Array{RGB, 2}, вам может быть лучше отказаться от графического процессора, поскольку данные в любом случае возвращаются обратно на процессор. Возможно, есть какой-то способ сделать это полностью на графическом процессоре, но я не знаю, как это сделать. - person DNF; 20.10.2020
comment
Кстати, этот тип вопроса хорошо подходит для того, чтобы задать его на discourse.julialang.org (не забудьте включить ссылку на этот вопрос, в таком случае.) - person DNF; 20.10.2020
comment
Спасибо за определение проблемы, это мне очень помогает. - person atachsin; 20.10.2020
comment
Вы можете вернуться к ЦП с помощью Array(afa), где afa — это ваш AFArray. См. README: github.com/JuliaGPU/ArrayFire.jl - person tholy; 20.10.2020
comment
Передача массива в ЦП с помощью Array(afa) и последующее преобразование устранили время ожидания. - person atachsin; 26.10.2020