Преобразование 8-битного изображения в 24 бит [дубликат]

Давайте сначала проанализируем вашу программу. В вашей программе ваш первый метод main(), и помните, что это статический метод ... Затем вы объявляете локальную переменную для этого метода (compareCount, low, high , и т.д..). Область действия этой переменной - это только объявленный метод, независимо от того, что это статический или нестационарный метод. Таким образом, вы не можете использовать эти переменные вне этого метода. Это основная ошибка u.

Затем мы переходим к следующей точке. Вы сказали, что статичность убивает вас. (Это может убить вас, но это дает жизнь вашей программе!) Сначала вы должны понять основную вещь. * Статический метод вызывает только статический метод и использует только статическую переменную. * Статическая переменная или статический метод не зависят от какого-либо экземпляра этого класса. (т. е. если вы измените какое-либо состояние статической переменной, оно будет отражено во всех объектах класса). Из-за этого вы называете это переменной класса или методом класса. И многое другое о «статическом» ключевом слове. Надеюсь, теперь у вас есть идея. Сначала измените область действия переменной и объявите ее как статическую (чтобы использовать ее в статических методах).

И совет для вас: вы неправильно поняли идею сферы переменных и статические функции. Получите ясное представление об этом.

164
задан Paweł Polewicz 24 May 2009 в 11:36
поделиться

13 ответов

Вы можете использовать PyPNG . Это чистый Python (без зависимостей) с открытым исходным кодом PNG-кодировщик / декодер, и он поддерживает запись массивов NumPy в виде изображений.

39
ответ дан Green-Man 25 August 2018 в 06:22
поделиться
  • 1
    Не забудьте масштабировать значения в правом диапазоне для PNG, обычно 0..255. Диапазоны значений в нейронных сетях часто равны 0..1 или -1.1. – Tomáš Gavenčiak 31 March 2018 в 18:49
  • 2
    PyPNG - чистый Python, который уменьшает внешние зависимости, но делает его намного медленнее, чем PIL и его производные классы. Например, сохранение изображения 3000x4000 на моей машине заняло 4,05 секунды с помощью PyPNG, но всего 0,59 секунды с помощью scipy.misc.imsave (6 раз быстрее). – Zvika 2 May 2018 в 11:25
115
ответ дан AryanJ-NYC 25 August 2018 в 06:22
поделиться

matplotlib svn имеет новую функцию для сохранения изображений только как изображение - без осей и т. д., это очень простая функция для резервного копирования, если вы не хотите устанавливать svn (скопировано прямо из image.py в matplotlib svn , для краткости удалили docstring):

def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None, origin=None):
    from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
    from matplotlib.figure import Figure

    fig = Figure(figsize=arr.shape[::-1], dpi=1, frameon=False)
    canvas = FigureCanvas(fig)
    fig.figimage(arr, cmap=cmap, vmin=vmin, vmax=vmax, origin=origin)
    fig.savefig(fname, dpi=1, format=format)
4
ответ дан Autoplectic 25 August 2018 в 06:22
поделиться

Добавление к ответу @ ideaman42:

def saveAsPNG(array, filename):
    import struct
    if any([len(row) != len(array[0]) for row in array]):
        raise ValueError, "Array should have elements of equal size"

                                #First row becomes top row of image.
    flat = []; map(flat.extend, reversed(array))
                                 #Big-endian, unsigned 32-byte integer.
    buf = b''.join([struct.pack('>I', ((0xffFFff & i32)<<8)|(i32>>24) )
                    for i32 in flat])   #Rotate from ARGB to RGBA.

    data = write_png(buf, len(array[0]), len(array))
    f = open(filename, 'wb')
    f.write(data)
    f.close()

Итак, вы можете сделать:

saveAsPNG([[0xffFF0000, 0xffFFFF00],
           [0xff00aa77, 0xff333333]], 'test_grid.png')

Произведение test_grid.png:

Grid of red, yellow, dark-aqua, grey [/g0]

(Прозрачность также работает, уменьшая старший байт с 0xff.)

9
ответ дан Evgeni Sergeev 25 August 2018 в 06:22
поделиться

Предполагая, что вы хотите изображение в оттенках серого:

im = Image.new('L', (width, height))
im.putdata(an_array.flatten().tolist())
im.save("image.tiff")
1
ответ дан Guillaume Lebreton 25 August 2018 в 06:22
поделиться
1
ответ дан hans_meine 25 August 2018 в 06:22
поделиться

Pure Python (2 & amp; 3), фрагмент без зависимостей сторонних разработчиков.

Эта функция записывает сжатые, true-color (4 байта на пиксель) RGBA PNG.

def write_png(buf, width, height):
    """ buf: must be bytes or a bytearray in Python3.x,
        a regular string in Python2.x.
    """
    import zlib, struct

    # reverse the vertical line order and add null bytes at the start
    width_byte_4 = width * 4
    raw_data = b''.join(
        b'\x00' + buf[span:span + width_byte_4]
        for span in range((height - 1) * width_byte_4, -1, - width_byte_4)
    )

    def png_pack(png_tag, data):
        chunk_head = png_tag + data
        return (struct.pack("!I", len(data)) +
                chunk_head +
                struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head)))

    return b''.join([
        b'\x89PNG\r\n\x1a\n',
        png_pack(b'IHDR', struct.pack("!2I5B", width, height, 8, 6, 0, 0, 0)),
        png_pack(b'IDAT', zlib.compress(raw_data, 9)),
        png_pack(b'IEND', b'')])

... Данные должны быть записаны непосредственно в файл, открытый как двоичный, например:

data = write_png(buf, 64, 64)
with open("my_image.png", 'wb') as fd:
    fd.write(data)

47
ответ дан ideasman42 25 August 2018 в 06:22
поделиться
  • 1
    Кажется, это именно то, что я ищу, но могли бы вы добавить некоторые комментарии? Я не вижу, как это записывается в файл. Вам нужно написать вывод в ранее открытом файле? Благодаря! – PhilMacKay 22 November 2013 в 23:28
  • 2
    @PhilMacKay, данные просто должны быть записаны в двоичный файл. добавил комментарий. – ideasman42 23 November 2013 в 01:31
  • 3
    Может ли кто-нибудь указать, в каком формате должно находиться изображение (buf)? Кажется, это не массивный массив ... – christianbrodbeck 2 April 2014 в 21:28
  • 4
    @christianmbrodbeck, массив байтов (RGBA RGBA ...) – ideasman42 2 April 2014 в 21:51
  • 5
    Хороший код! – Robotbugs 22 May 2016 в 04:24

Если у вас есть matplotlib, вы можете сделать:

import matplotlib.pyplot as plt
plt.imshow(matrix) #Needs to be in row,col order
plt.savefig(filename)

Это сохранит график (а не сами изображения).

41
ответ дан Mona Jalal 25 August 2018 в 06:22
поделиться
  • 1
    Перед imshow нужно добавить plt.figure () и plot.show () – Framester 16 August 2011 в 14:38
  • 2
    Нет, для интерфейса pyplot plt.figure () является излишним. Кроме того, вам нужно только plt.show (), если вы хотите увидеть окно с рисунком, - в этом случае желательно сохранить файл изображения, поэтому не нужно было вызывать show (). – DopplerShift 22 August 2011 в 20:42
  • 3
    Используя это. Но страдание от утечки памяти – SolessChong 20 August 2014 в 09:31
  • 4
  • 5
    не будет работать, если вы запустите скрипт на удаленном хосте, используя его без поддержки графического интерфейса. – Temak 18 December 2015 в 13:54
  • 6
    Если вы хотите показать изображение в записной книжке, вы можете добавить следующее: & gt; & gt; & quot; из IPython.display import Image & quot; и затем & gt; & gt; & quot; Изображение (имя_файла = имя_файла) & quot; – Robert 23 February 2016 в 15:17
  • 7
    matplotlib.imsave () в новых версиях – Vinay Lodha 12 February 2018 в 15:12
  • 8
    Это matplotlib.pyplot.imsave в matplotlib 2+ – Alexey Petrenko 17 February 2018 в 03:36
  • 9
    Это то, что сработало для меня :) (все остальное выше нужно PIL, который был только python 2) – Hugh Perkins 8 August 2018 в 13:41
  • 10
    @HughPerkins попробовать Pillow в качестве замены PIL в Python 3 – christianbrodbeck 9 August 2018 в 00:51

Вы можете использовать библиотеку skimage в Python

Пример:

from skimage.io import imsave
imsave('Path_to_your_folder/File_name.jpg',your_array)
8
ответ дан PURNENDU MISHRA 25 August 2018 в 06:22
поделиться

Это использует PIL, но, возможно, некоторым может показаться полезным:

import scipy.misc
scipy.misc.imsave('outfile.jpg', image_array)

EDIT: Текущая версия scipy начала нормализовать все изображения, чтобы мин (данные) становились черными и максимальными (данные ) станет белым. Это нежелательно, если данные должны быть точными уровнями серого или точными каналами RGB. Решение:

import scipy.misc
scipy.misc.toimage(image_array, cmin=0.0, cmax=...).save('outfile.jpg')
196
ответ дан Steve Tjoa 25 August 2018 в 06:22
поделиться
  • 1
    imsave живет в ... / scipy / misc / pilutil.py, который использует PIL – denis 16 April 2010 в 10:46
  • 2
    Ах, я не знал. Спасибо за ссылку. – Steve Tjoa 16 April 2010 в 19:34
  • 3
    Будьте осторожны при преобразовании в jpg, поскольку он является потерянным, и поэтому вы не сможете восстановить точные данные, используемые для создания изображения. – Feanil 20 December 2012 в 17:20
  • 4
    Это теперь устарело в использовании scipy 0.19 - scipy.io.imwrite – g.stevo 19 April 2017 в 21:56
  • 5
    «imsave» устарел в SciPy 1.0.0 и будет удален в 1.2.0 ». ( Scipy 1.1.0 doc ) – noobar 10 July 2018 в 01:47

Если вы работаете в среде python Spyder, то это не может быть проще, чем просто щелкнуть правой кнопкой мыши массив в проводнике переменных, а затем выбрать параметр «Показать изображение».

Это попросит вас сохранить изображение в dsik, в основном в формате PNG.

Библиотека PIL в этом случае не понадобится.

0
ответ дан sɐunıɔןɐqɐp 25 August 2018 в 06:22
поделиться

В мире, вероятно, не нужен еще один пакет для записи массива numpy в файл PNG, но для тех, кто не может получить достаточное количество, я недавно установил numpngw в github:

https://github.com/WarrenWeckesser/numpngw

и на pypi: https://pypi.python.org/pypi/numpngw/

Единственная внешняя зависимость - numpy.

Вот первый пример из каталога examples репозитория. Существенной линией является просто

write_png('example1.png', img)

, где img является массивом numpy. Весь код перед этой строкой - это операторы импорта и код для создания img.

import numpy as np
from numpngw import write_png


# Example 1
#
# Create an 8-bit RGB image.

img = np.zeros((80, 128, 3), dtype=np.uint8)

grad = np.linspace(0, 255, img.shape[1])

img[:16, :, :] = 127
img[16:32, :, 0] = grad
img[32:48, :, 1] = grad[::-1]
img[48:64, :, 2] = grad
img[64:, :, :] = 127

write_png('example1.png', img)

Вот файл PNG, который он создает:

2
ответ дан Warren Weckesser 25 August 2018 в 06:22
поделиться
  • 1
    Мне любопытно, как ваша библиотека отличается от других? Это быстрее? Есть ли у него причудливые функции? – F Lekschas 12 March 2018 в 05:22
  • 2
    Несколько функций: (1) Он использует массивы numpy. (2) Он написан с использованием только python и numpy, поэтому для него не требуется установка библиотеки C. (3) Он может создавать анимированные PNG-файлы. (4) Он предоставляет класс для написания анимации matplotlib в виде анимированных PNG-файлов. – Warren Weckesser 12 March 2018 в 05:29
  • 3
    Благодаря! Мне было бы любопытно, как это сравнивается с stackoverflow.com/a/19174800/981933 с точки зрения производительности, которая также является чистым python. Первый метод выше 2x быстрее, чем PIL, что довольно удивительно. Nevermind, если это не ваша цель :) – F Lekschas 12 March 2018 в 05:58

Есть opencv для python ( http://docs.opencv.org/trunk/doc/py_tutorials/py_tutorials.html ).

import cv2
import numpy as np

cv2.imwrite("filename.png", np.zeros((10,10)))

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

24
ответ дан Xocoatzin 25 August 2018 в 06:22
поделиться
  • 1
    Почему массив размером 10? Что привело к выбору 10, используемых в этом решении? – Gathide 10 May 2017 в 07:44
  • 2
    – Xocoatzin 10 May 2017 в 18:23
  • 3
    Как я могу добавить что-то вроде cmap="gray", когда я сохраняю изображение с помощью cv2? – Mona Jalal 13 June 2017 в 02:55
Другие вопросы по тегам:

Похожие вопросы: