Как сохранить значения CSV из файла в массив numpy в Python? - PullRequest
1 голос
/ 29 марта 2020

Я написал сценарий Python, который читает черно-белое растровое изображение и сохраняет значение каждого пикселя в виде шестнадцатеричного значения от 0x00 до 0xFF в файле .txt. Значения хранятся в виде непрерывного одномерного массива, разделенного запятыми, и чтобы не иметь очень широких файлов, строки имеют длину только , максимальную длину 16 элементов, например:

v01, v02, ... , v15, v16,
v17, v18, ... , v31, v32,
...
0x00, 0x00, ... , 0x00, 0x00,
0x00, 0x00, ... , 0x00, 0x00,
...

Обратите внимание, что последний элемент каждой строки также имеет запятую

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

Теперь, чтобы проверить, что преобразование сделано правильно, мне нужно написать скрипт, который читает файл и сохраняет значения в массиве numpy, который используется для отображения изображения позже с помощью "matplotlib". Я пробовал следующий код:

my_data = genfromtxt('file.txt', delimiter=',')
print(my_data)

Проблема в том, что, кроме неправильных измерений, шестнадцатеричные значения не читаются как числа и что элемент после последней запятой строки Также прочитайте (я думаю, что символ прерывания). Я получаю что-то вроде:

[nan, nan, ... , nan, nan," "
...]

Мне нужен способ чтения файла .txt, преобразование значений из формата "0x00" в значение цифра c и сохранение затем в массиве amxn numpy (m & n - известные параметры, исходный размер растрового изображения):

[[0, 0, ... , 0, 0]
 [0, 0, ... , 0, 0]
 ...]

Есть предложения, как это сделать?


Обновление

При написании вопроса я работал только с файлами, кратными 16 пикселям в ширину, что гарантировало, что мои выходные данные csv всегда имели 16 элементов во всех строках. Но после некоторого тестирования я наткнулся на картинку, размер которой сделал последний ряд csv менее 16 элементов. В этом случае я не смог использовать решение, предоставленное @taras, но все же ответ был правильным в соответствии с моим первоначальным вопросом.

Наконец, я получил следующий код, возможно, не такой элегантный, но трюк:

with open(filename,"r") as f:
        pixels=[x.split(',') for x in f.readlines()]
        for p in pixels:
            del p[-1]
        pixels = [int(p,16) for row in pixels for p in row]
        pixels = np.asarray(pixels, dtype=np.uint8).reshape(h,w)

Я держу оба ответа на случай, если кто-то посчитает их полезными.

1 Ответ

1 голос
/ 29 марта 2020

Поскольку у вас есть фиксированное количество столбцов, вы можете использовать его, чтобы прочитать только первые 16 столбцов (это позволит вам убрать запятую), и преобразовать каждый столбец из шестнадцатеричного числа, используя converters dict с int(x, 16) :

import numpy as np

fname = 'file.txt'
num_cols = 16
np.loadtxt(fname, usecols=range(num_cols), dtype=np.uint8, delimiter=',',
           converters={k: lambda x: int(x, 16) for k in range(num_cols)})

Редактировать:
Если число элементов в файле не кратно 16, вы можете использовать обычный код python для предварительной обработки данных, а затем преобразовать это в numpy массив:

import numpy as np

fname = 'file.txt'
with open(fname) as fp:
    data = fp.read().replace('\n', '')
np.array([int(x, 16) for x in data.split(',')])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...