Как я должен хранить растровое изображение в памяти для обработки?

#python #image-processing #bitmap

#питон #обработка изображений #растровое изображение

Вопрос:

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

 image.seek(0) file_type = image.read(2) print(f"File Type: {file_type.decode('ascii')}")  meta = image.read(12) file_size, _, _, offset = unpack("lt;I2HI", meta) print(f"File Size: {file_size}") print(f"Header Offset: {offset}") image_header = image.read(40)  header_size, image_width, image_height,  color_planes, bits_per_pixel, compression,  image_size, horizontal_reso, vertical_reso, color_palette, important_color = unpack("lt;3I2h2I4I", image_header)  print(f"Header size: {header_size}") print(f'Width: {image_width} | Height: {image_height}') print(f"Bits per pixel: {bits_per_pixel}") print(f"Image size: {image_size}") print(f"Horizontal reso: {horizontal_reso} | Vertical reso: {vertical_reso}") print(f"Color palette: {color_palette}") raw_image = image.read()  def calculate_row_size(bits_per_pixel, image_width):  return math.ceil((bits_per_pixel * image_width)/32)*4  def calculate_row_padding(bits_per_pixel, image_width):  return ((bits_per_pixel//8) * image_width) % 4  def calculate_pixel_array_size(row_size, image_height):  return row_size * abs(image_height)  def calculate_number_of_rows(row_size, pixel_array_size):  return pixel_array_size//row_size  row_size = calculate_row_size(bits_per_pixel, image_width) pixel_array_size = calculate_pixel_array_size(row_size, image_height) number_of_rows = calculate_number_of_rows(row_size, pixel_array_size) row_pad = calculate_row_padding(bits_per_pixel, image_width)  print(f"Row size: {row_size}") print(f"Pixel array size: {pixel_array_size}") print(f"Number of rows: {number_of_rows}") print(f"Padding size: {row_pad}")  final_image = b''  def chunk(data, n):  for i in range(0, len(data), n):  yield i, data[i:i n]  for i, data in chunk(raw_image, row_size):  for i, rgb in chunk(data, 3):  avg = sum(rgb)//3  final_image  = avg.to_bytes((avg.bit_length()   7)//8, 'little')  

В конце концов, я пытаюсь преобразовать в оттенки серого (очень неэффективно). Моей мыслью было создать список списков, в которых данные пикселей будут храниться в стиле массива NumPy. Любой вклад был бы полезен.

Комментарии:

1. использовать numpy . очень удобно. вы могли бы побеспокоиться о встроенном array типе python (и модуле), но эх. — ввод-вывод изображения для обмана/проверки можно выполнить с помощью OpenCV, PIL/pillow, scikit-image, … и все они совместимы с numpy

2. Я знаю, что могу легко сделать это с numpy. Я просто пытаюсь избежать использования каких-либо библиотек.

3. можно обмануть, если вы используете его только в качестве контейнера. вы могли бы написать свой собственный класс, который хранит все это в bytearray (встроенный тип python).