Преобразование и сохранение изображения в оттенках серого, например, в цветовую схему viridis - PullRequest
2 голосов
/ 27 апреля 2020

Допустим, у меня есть изображение :

enter image description here

Я хочу преобразовать шкалу серого в цветовую схему viridis и сохранить Это. Я получил его на работу, используя этот код кода:

system('wget https://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/Von_einem_Schrecklichen_vnd_Wunderbarlichen_Cometen_so_sich_den_Dienstag_nach_Martini_dieses_lauffenden_M._D._Lxxvij._Jahrs_am_Himmel_erzeiget_hat_%28grayscale%29.png/320px-thumbnail.png')
library(png)
library(viridisLite)
x <- png::readPNG('320px-thumbnail.png')
x <- x[, ,1]
intmat <- x * 255
image(1:nrow(intmat), 1:ncol(intmat), intmat, col=viridis(256))

Что приводит к этому:

enter image description here

Я очень доволен тем, как была применена цветовая схема. Однако это уже не оригинальное изображение, а просто сюжет. Я хочу обменять каждый пиксель в градациях серого и снова сохранить преобразованное изображение в формате png, без использования image(). Я взглянул на функцию image_convert в магии, но не мог понять, как получить желаемое поведение.

Ответы [ 2 ]

3 голосов
/ 27 апреля 2020

Я уверен, что есть способы сделать это, не изобретая велосипед, но используя только загруженные вами библиотеки, довольно просто манипулировать цветами viridis, разделить их на 3 канала и сохранить как png.

Вот функция для выполнения любого png:

png_to_viridis <- function(in_file, out_file)
{
  PNG_raw <- readBin(in_file, "raw", 10e6)
  x <- png::readPNG(PNG_raw)
  intmat <- 255 * x[, ,1] 
  virmat <- viridisLite::viridis(256)[intmat + 1]
  virmat <- c(substr(virmat, 2, 3), substr(virmat, 4, 5), 
              substr(virmat, 6, 7), substr(virmat, 8, 9))
  virmat <- as.numeric(as.hexmode(virmat))/255
  dim(virmat) <- c(dim(intmat), 4)
  png::writePNG(virmat, out_file)
}

Так что теперь, если я это сделаю:

png_to_viridis("https://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/Von_einem_Schrecklichen_vnd_Wunderbarlichen_Cometen_so_sich_den_Dienstag_nach_Martini_dieses_lauffenden_M._D._Lxxvij._Jahrs_am_Himmel_erzeiget_hat_%28grayscale%29.png/320px-thumbnail.png",
               "viridis.png")

, я получаю следующий результат, сохраненный как viridis.png:

enter image description here

0 голосов
/ 27 апреля 2020

Я извлек цветовую карту Verdis из Mathplotpy из https://matplotlib.org/3.1.1/tutorials/colors/colormap-manipulation.html и преобразовал ее в набор цветов в формате ImageMagick. Затем создал 1-мерное цветное изображение карты и с помощью ImageMagick -clut примените его к изображению.

Ввод:

enter image description here

convert picture.png \
\( -size 1x1 \
xc:"rgba(0.267004,0.004874,0.329415,1.)" \
xc:"rgba(0.283072,0.130895,0.449241,1.)" \
xc:"rgba(0.262138,0.242286,0.520837,1.)" \
xc:"rgba(0.220057,0.343307,0.549413,1.)" \
xc:"rgba(0.177423,0.437527,0.557565,1.)" \
xc:"rgba(0.143343,0.522773,0.556295,1.)" \
xc:"rgba(0.119512,0.607464,0.540218,1.)" \
xc:"rgba(0.166383,0.690856,0.496502,1.)" \
xc:"rgba(0.319809,0.770914,0.411152,1.)" \
xc:"rgba(0.525776,0.833491,0.288127,1.)" \
xc:"rgba(0.762373,0.876424,0.137064,1.)" \
xc:"rgba(0.993248,0.906157,0.143936,1.)" \
-append \) -clut -evaluate multiply 255 PNG24:picture_verdis.png


Результат:

enter image description here

Используйте PNG8: вместо PNG24: если вы хотите 8-битный цвет, а не 24-битный цвет.

Обратите внимание, что цвета ImageMagick rgb находятся в диапазоне от 0 до 255, а Mathplotpy использует диапазон от 0 до 1. Поэтому мне пришлось умножить результат на 255. В конце.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...