Раскрашиваем ч/б фото с помощью Python
Привет Хабр.
Одной из интересных и популярных (особенно перед разными юбилеями) задач является «раскрашивание» старых черно-белых фотографий и даже фильмов. Тема это достаточно интересная, как с математической, так и с исторической точки зрения. Мы рассмотрим реализацию этого процесса на Python, который любой желающий сможет запустить на своем домашнем ПК.
Результат работы на фото.
Для тех кому интересно, принцип работы, исходники и примеры под катом.
Принцип работы
Итак, у нас есть черно-белые фото, которые делались в то время, когда цветной печати еще не было. Что это значит для нас — что информация о цвете в этих фото физически отсутствует, взять её оттуда мы не можем. Есть два варианта — либо раскрашивать вручную (чем занимаются некоторые специально обученные люди, что может включать в себя не только раскрашивание, но и работу с архивами, музеями и пр), либо призвать всю мощь машинного обучения, и пусть черновую работу за нас делает компьютер.
Основной подход по сути прост. Первым шагом мы переводим изображение в формат Lab, который содержит раздельно яркостную (L) и цветовую (аb) составляющие. L-канал это фактически и есть искомое черно-белое фото.
Вторым шагом мы обучаем нейросеть, которая по каналу L сможет «угадывать» для нас недостающие цветовые каналы. Для этого нужно много цветных изображений, которые будут использоваться для обучения.
И наконец, когда все готово, мы можем использовать обученную нейросеть для раскрашивания черно-белых фотографий.
Мы рассмотрим два подхода — реализацию нейросети с нуля, и использование «профессиональной» предобученной нейросети. Первый способ скорее учебный, и желающие посмотреть на практические результаты могут сразу перейти ко второму.
Способ 1. Реализация «с нуля» в Keras
Приступим к коду. Рассмотрим пример реализации от Emil Wallner, его код на github можно посмотреть по ссылке.
Загрузка фотографий
Тут ничего необычного. Загружаем массив и приводим цвета к диапазону 0..1. Как можно видеть, нейросеть работает с изображениями 256×256. Немного, но даже это уже на пределе возможностей современных «домашних» видеокарт — при обучении сети я периодически получал сообщение Out Of Memory.
import numpy as np import cv2 IMG_SIZE = 256 def load_train_images(folder): x = [] for filename in os.listdir(folder): x.append(img_to_array(load_img(folder + os.sep + filename))) x = np.array([cv2.resize(i, (IMG_SIZE, IMG_SIZE)) for i in x], dtype=float)/255.0 return x
Подготовка данных
Здесь используется класс ImageDataGenerator, который позволяет из одного изображения получить несколько. Как можно видеть, в качестве параметров передаются zoom_range=0.2, rotation_range=20, horizontal_flip=True, т.е. из одного изображения будет создано несколько с разным поворотом, увеличением и отражением по горизонтали.
from skimage.color import rgb2lab, lab2rgb, rgb2gray, xyz2lab from keras. preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img from keras.layers import Conv2D, UpSampling2D, InputLayer, Conv2DTranspose from keras.layers import Activation, Dense, Dropout, Flatten datagen = ImageDataGenerator(shear_range=0.2, zoom_range=0.2, rotation_range=20, horizontal_flip=True) # Generate training data def image_a_b_gen(batch_size): for batch in datagen.flow(train_images, batch_size=batch_size): lab_batch = rgb2lab(batch) x_batch = lab_batch[:, :, :, 0] y_batch = lab_batch[:, :, :, 1:] / 128 yield (x_batch.reshape(x_batch.shape + (1,)), y_batch)
Внутри самого генератора происходит вызов функции rgb2lab, и берутся соответствующие каналы.
Обучение нейронной сети
Как можно видеть, здесь используется достаточно многослойная сверточная сеть, которая настроена так, что результирующее изображение имеет такой же размер, что и входное.
model = Sequential() model. add(InputLayer(input_shape=(IMG_SIZE, IMG_SIZE, 1))) model.add(Conv2D(64, (3, 3), activation='relu', padding='same')) model.add(Conv2D(64, (3, 3), activation='relu', padding='same', strides=2)) model.add(Conv2D(128, (3, 3), activation='relu', padding='same')) model.add(Conv2D(128, (3, 3), activation='relu', padding='same', strides=2)) model.add(Conv2D(256, (3, 3), activation='relu', padding='same')) model.add(Conv2D(256, (3, 3), activation='relu', padding='same', strides=2)) model.add(Conv2D(512, (3, 3), activation='relu', padding='same')) model.add(Conv2D(256, (3, 3), activation='relu', padding='same')) model.add(Conv2D(128, (3, 3), activation='relu', padding='same')) model.add(UpSampling2D((2, 2))) model.add(Conv2D(64, (3, 3), activation='relu', padding='same')) model.add(UpSampling2D((2, 2))) model.add(Conv2D(32, (3, 3), activation='relu', padding='same')) model.add(Conv2D(2, (3, 3), activation='tanh', padding='same')) model.add(UpSampling2D((2, 2))) model.compile(optimizer='rmsprop', loss='mse') model.fit_generator(image_a_b_gen(batch_size=50), steps_per_epoch=steps_per_epoch, epochs=epochs)
Собственно раскрашивание состоит в подготовке L-канала (ч/б фото), вызову нейронной сети и объединении каналов вместе.
output = model.predict(data_in) for i in range(len(output)): cur = np.zeros((256, 256, 3)) cur[:,:,0] = color_me[i][:,:,0] cur[:,:,1:] = output[i] * 128 img_rgb = lab2rgb(cur)*brightness_corr imsave(folder_dst + os.sep + "img_%d.png" % i, img_rgb.astype(np.uint8))
В общем, и вся «магия».
Увы, добиться стабильной работы от этой программы так и не удалось, иногда она показывает неплохие результаты, иногда вообще ничего, так что этот пример можно лишь рассматривать как учебный. Желающие могут посмотреть результаты на github, исходники можно взять там же. Для тех кому лень идти на github, код целиком приведен под спойлером.
colorize1. py
import os # os.environ["CUDA_VISIBLE_DEVICES"] = "-1" # Force CPU os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' # 0 = all messages are logged, 3 - INFO, WARNING, and ERROR messages are not printed from keras.layers import Conv2D, Conv2DTranspose, UpSampling2D from keras.layers import Activation, Dense, Dropout, Flatten, InputLayer from keras.layers.normalization import BatchNormalization from keras.callbacks import TensorBoard from keras.models import Sequential from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img from skimage.color import rgb2lab, lab2rgb, rgb2gray from skimage.io import imsave import numpy as np import random import tensorflow as tf import cv2 folder_train = "Faces" folder_src = "Input" folder_dst = "Output" model_file = "faces1.h5" brightness_corr = 250 do_train = True # Get train images X = [] for filename in os.listdir(folder_train): X.append(img_to_array(load_img(folder_train + os.sep + filename))) X = np.array([cv2.resize(i, (256, 256)) for i in X], dtype=float)/255.0 # X = np.array(X, dtype=float) Xtrain = X # Model model = Sequential() model.add(InputLayer(input_shape=(256, 256, 1))) model.add(Conv2D(64, (3, 3), activation='relu', padding='same')) model.add(Conv2D(64, (3, 3), activation='relu', padding='same', strides=2)) model.add(Conv2D(128, (3, 3), activation='relu', padding='same')) model.add(Conv2D(128, (3, 3), activation='relu', padding='same', strides=2)) model.add(Conv2D(256, (3, 3), activation='relu', padding='same')) model.add(Conv2D(256, (3, 3), activation='relu', padding='same', strides=2)) model.add(Conv2D(512, (3, 3), activation='relu', padding='same')) model.add(Conv2D(256, (3, 3), activation='relu', padding='same')) model.add(Conv2D(128, (3, 3), activation='relu', padding='same')) model.add(UpSampling2D((2, 2))) model.add(Conv2D(64, (3, 3), activation='relu', padding='same')) model.add(UpSampling2D((2, 2))) model.add(Conv2D(32, (3, 3), activation='relu', padding='same')) model.add(Conv2D(2, (3, 3), activation='tanh', padding='same')) model. add(UpSampling2D((2, 2))) model.compile(optimizer='rmsprop', loss='mse') # Image transformer datagen = ImageDataGenerator(shear_range=0.2, zoom_range=0.2, rotation_range=20, horizontal_flip=True) # Generate training data batch_size = 10 def image_a_b_gen(batch_size): for batch in datagen.flow(Xtrain, batch_size=batch_size): lab_batch = rgb2lab(batch) X_batch = lab_batch[:,:,:,0] Y_batch = lab_batch[:,:,:,1:] / 128 yield (X_batch.reshape(X_batch.shape+(1,)), Y_batch) if do_train: # Train model model.fit_generator(image_a_b_gen(batch_size), epochs=1, steps_per_epoch=400) # Save model model.save_weights(model_file) # Load model model.load_weights(model_file) # Process images color_me = [] for filename in os.listdir(folder_src): color_me.append(img_to_array(load_img(folder_src + os.sep + filename))) color_me = np.array([cv2.resize(i, (256, 256)) for i in color_me], dtype=float) # color_me = np.array(color_me, dtype=float) color_me = rgb2lab(1. 0/255*color_me)[:,:,:,0] color_me = color_me.reshape(color_me.shape+(1,)) # Test model output = model.predict(color_me) # Output colorizations for i in range(len(output)): cur = np.zeros((256, 256, 3)) cur[:,:,0] = color_me[i][:,:,0] cur[:,:,1:] = output[i] * 128 img_rgb = lab2rgb(cur)*brightness_corr imsave(folder_dst + os.sep + "img_%d.png" % i, img_rgb.astype(np.uint8)) print("img_%d.png saved" % i)
Способ 2. Предобученная сеть
В качестве второго метода рассмотрим уже готовую нейронную сеть от Rich Zhang. Это гораздо более серьезный проект, нейросеть была обучена на 1.3млн изображений, и только лишь файлы сохраненной модели для этой сети занимают около 300Мбайт.
Шаг 1. Скачиваем файлы модели:
Загружаем файлы colorization_deploy_v2.prototxt, colorization_release_v2.caffemodel и pts_in_hull.npy, кладем их в папку models.
Шаг 2. Загружаем модель нейронной сети
def load_model() -> Any: # Load serialized black and white colorizer model and cluster # The L channel encodes lightness intensity only # The a channel encodes green-red. # And the b channel encodes blue-yellow print("Loading model...") prototxt = "models/colorization_deploy_v2.prototxt" model = "models/colorization_release_v2.caffemodel" points = "models/pts_in_hull.npy" net = cv2.dnn.readNetFromCaffe(prototxt, model) pts = np.load(points) # Add the cluster centers as 1x1 convolutions to the model: class8 = net.getLayerId("class8_ab") conv8 = net.getLayerId("conv8_313_rh") pts = pts.transpose().reshape(2, 313, 1, 1) net.getLayer(class8).blobs = [pts.astype("float32")] net.getLayer(conv8).blobs = [np.full([1, 313], 2.606, dtype="float32")] return net
Шаг 3. Раскрашиваем изображения. Принцип такой же, как и в нашем «учебном» примере: получаем каналы в Lab, конвертируем их в RGB и записываем в файл.
def colorize_image(net: Any, image_in: str, image_out: str): # Load the input image, scale it and convert it to Lab: image = cv2.imread(image_in) height, width, channels = image. shape # image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB) # Extracting "L" scaled = image.astype("float32") / 255.0 lab = cv2.cvtColor(scaled, cv2.COLOR_RGB2LAB) # Resize to network size resized = cv2.resize(lab, (224, 224)) L = cv2.split(resized)[0] L -= 50 # Predicting "a" and "b" net.setInput(cv2.dnn.blobFromImage(L)) ab = net.forward()[0, :, :, :].transpose((1, 2, 0)) # Creating a colorized Lab photo (L + a + b) L = cv2.split(lab)[0] ab = cv2.resize(ab, (width, height)) colorized = np.concatenate((L[:, :, np.newaxis], ab), axis=2) # Convert to RGB colorized = cv2.cvtColor(colorized, cv2.COLOR_LAB2RGB) colorized = np.clip(colorized, 0, 1) colorized = (255 * colorized).astype("uint8") cv2.imwrite(image_out, cv2.cvtColor(colorized, cv2.COLOR_RGB2BGR)) print("Image %s saved" % image_out)
Результаты
В качестве исходных файлов я взял следующие фотографии:
Результат неидеален, но в принципе не так уж плох:
Важно иметь в виду, что нейросеть работает с изображениями 224х224, так что High-Res получить увы, не удастся — изображение на выходе будет иметь оригинальное разрешение (L-канал), но канал цвета будет масштабирован из 224х224. Хотя если этого не знать, то заметить цветовые артефакты не так и просто, цветовая разрешающая способность глаза в несколько раз ниже яркостной:
На КДПВ принцип тот же.
Для желающих поэкспериментировать самостоятельно с разными картинками, исходник под спойлером.
colorize2.py
import numpy as np from typing import * import cv2 import os # Sources: # https://www.learnopencv.com/convolutional-neural-network-based-image-colorization-using-opencv/ # https://www.pyimagesearch.com/2019/02/25/black-and-white-image-colorization-with-opencv-and-deep-learning/ # http://richzhang.github.io/colorization/ # Models: # http://eecs.berkeley.edu/~rich.zhang/projects/2016_colorization/files/demo_v2/colorization_release_v2.caffemodel # http://eecs.berkeley.edu/~rich.zhang/projects/2016_colorization/files/demo_v2/colorization_release_v2_norebal.caffemodel # http://eecs.berkeley.edu/~rich.zhang/projects/2016_colorization/files/demo_v1/colorization_release_v1. caffemodel prototxt = "models/colorization_deploy_v2.prototxt" model = "models/colorization_release_v2.caffemodel" points = "models/pts_in_hull.npy" folder_in = "Input" folder_out = "Output" def load_model() -> Any: # Load serialized black and white colorizer model and cluster # The L channel encodes lightness intensity only # The a channel encodes green-red. # And the b channel encodes blue-yellow print("Loading model...") net = cv2.dnn.readNetFromCaffe(prototxt, model) pts = np.load(points) # Add the cluster centers as 1x1 convolutions to the model: class8 = net.getLayerId("class8_ab") conv8 = net.getLayerId("conv8_313_rh") pts = pts.transpose().reshape(2, 313, 1, 1) net.getLayer(class8).blobs = [pts.astype("float32")] net.getLayer(conv8).blobs = [np.full([1, 313], 2.606, dtype="float32")] return net def colorize_image(net: Any, image_in: str, image_out: str): # Load the input image, scale it and convert it to Lab: image = cv2. imread(image_in) height, width, channels = image.shape # image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB) # Extracting "L" scaled = image.astype("float32") / 255.0 lab = cv2.cvtColor(scaled, cv2.COLOR_RGB2LAB) # Resize to network size resized = cv2.resize(lab, (224, 224)) L = cv2.split(resized)[0] L -= 50 # Predicting "a" and "b" net.setInput(cv2.dnn.blobFromImage(L)) ab = net.forward()[0, :, :, :].transpose((1, 2, 0)) # Creating a colorized Lab photo (L + a + b) L = cv2.split(lab)[0] ab = cv2.resize(ab, (width, height)) colorized = np.concatenate((L[:, :, np.newaxis], ab), axis=2) # Convert to RGB colorized = cv2.cvtColor(colorized, cv2.COLOR_LAB2RGB) colorized = np.clip(colorized, 0, 1) colorized = (255 * colorized).astype("uint8") cv2.imwrite(image_out, cv2.cvtColor(colorized, cv2.COLOR_RGB2BGR)) print("Image %s saved" % image_out) if __name__ == '__main__': net = load_model() for filename in os. listdir(folder_in): colorize_image(net, folder_in + os.sep + filename, folder_out + os.sep + filename.replace(".", "-out."))
Для запуска программы навыков программирования не требуется, достаточно уметь запустить программу из консоли, и положить исходные файлы в папку Input, цветные фото будет сгенерированы в папке Output (также необходимо скачать файлы модели из вышеприведенных ссылок в папку models).
Заключение
Как можно видеть, задача раскрашивания фото является весьма непростой с вычислительной точки зрения. Даже обучение нейросети, обрабатывающей файлы 224х224пкс, может требовать мощной видеокарты и нескольких часов или даже дней обучения. Существуют ли доступные нейросети, способные сделать хотя бы FullHD-качество, мне неизвестно.
Желающие могут изучить проект от Rich Chang более подробно, там же есть инструкции по обучению сети на разных датасетах, ну а готовый вышеприведенной код с уже обученной сетью можно просто запустить, он работает быстро и почти не требует ресурсов ПК.
Неплохую статью от mail.ru про раскрашивание фото военных времен можно почитать в их блоге, но разумеется, как и в любом корпоративном блоге, никаких исходников там нет и не будет.
И бонус для тех, кто дочитал до сюда. С помощью аналогичного подхода можно раскрашивать и видео, принцип точно такой же. Исходный код, принимающий и сохраняющий MP4, приведен под спойлером.
video.py
def colorize_video(net: Any, video_in: str, video_out: str): vid_in = cv2.VideoCapture(video_in) frames, fps = int(vid_in.get(cv2.CAP_PROP_FRAME_COUNT)), int(round(vid_in.get(cv2.CAP_PROP_FPS))) width, height = int(vid_in.get(cv2.CAP_PROP_FRAME_WIDTH)), int(vid_in.get(cv2.CAP_PROP_FRAME_HEIGHT)) print("Video {}: {}x{}, {} frames, {} fps".format(video_in, width, height, frames, fps)) size_out = (width, height) vid_out = cv2.VideoWriter(video_out, cv2.VideoWriter_fourcc(*"mp4v"), fps, size_out) # .mp4 # vid_out = cv2. VideoWriter(video_out, cv2.VideoWriter_fourcc(*'DIVX'), fps, size_out) # .avi count = 0 while True: success, frame = vid_in.read() if frame is None or success is False: break if (count % 10) == 0: print("Frame {} of {}".format(count, frames)) frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2RGB) scaled = frame.astype("float32") / 255.0 lab = cv2.cvtColor(scaled, cv2.COLOR_RGB2LAB) resized = cv2.resize(lab, (224, 224)) L = cv2.split(resized)[0] L -= 50 net.setInput(cv2.dnn.blobFromImage(L)) ab = net.forward()[0, :, :, :].transpose((1, 2, 0)) ab = cv2.resize(ab, (frame.shape[1], frame.shape[0])) L = cv2.split(lab)[0] colorized = np.concatenate((L[:, :, np.newaxis], ab), axis=2) colorized = cv2.cvtColor(colorized, cv2.COLOR_LAB2BGR) colorized = np.clip(colorized, 0, 1) colorized = (255 * colorized). astype("uint8") frame_out = colorized # cv2.cvtColor(colorized, cv2.COLOR_RGB2BGR) vid_out.write(frame_out) count += 1 vid_in.release() vid_out.release() print("File %s saved" % video_out)
Его достаточно вставить в вышеприведенную программу. Процесс обработки видео не быстрый, скорость порядка 1-2 кадров/с.
Как обычно, всем удачных экспериментов.
Можно объявить в комментариях конкурс на лучшее цветное ретро-фото 😉
Москва в ЧБ: chistoprudov — LiveJournal
?- Россия
- Город
- Cancel
Да, я никогда не обрабатывал и не выкладывал свои карточки в ЧБ, но тут по-другому и нельзя было.
Кто самый первый ответит правильно, тот — эрудит!
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
Каталог всех моих записей в блоге
Дмитрий Чистопрудов, фотоагентство Vostok. По вопросам проведения съемок пишите на электронную почту [email protected]
Tags: Город, Городской пейзаж, Москва, Подмосковье
Subscribe
Откуда столько мусора и нужно ли его сортировать?
Вторая часть репортажа Настоятельно рекомендую прочитать сначала первую часть, которая находится тут:…
Откуда столько мусора и нужно ли его сортировать?
— Все равно они потом все сваливают в одну кучу! — утверждает сосед по подъезду и кидает пакет с пищевыми отходами в контейнер для…
Телега, труба и инста!
Друзья, я запустил канал в телеграме t. me/vostokphotos и публикую там много всего интересного и разного. Начиная от коммерческих съемок промышленных…
Photo
Hint http://pics.livejournal.com/igrick/pic/000r1edq
Previous
← Ctrl
← Alt
- 1
- 2
- 3
Next
Ctrl →
Alt →
Откуда столько мусора и нужно ли его сортировать?
Вторая часть репортажа Настоятельно рекомендую прочитать сначала первую часть, которая находится тут:…
Откуда столько мусора и нужно ли его сортировать?
— Все равно они потом все сваливают в одну кучу! — утверждает сосед по подъезду и кидает пакет с пищевыми отходами в контейнер для…
Телега, труба и инста!
Друзья, я запустил канал в телеграме t. me/vostokphotos и публикую там много всего интересного и разного. Начиная от коммерческих съемок промышленных…
Четыре краеугольных камня превосходной черно-белой фотографии
Kent DuFault
Новое/достойное внимания
Этот краткий совет взят из нашего Better Black and White Premium Guide
Для фотографа нет ничего более увлекательного, чем создание великолепного черно-белого изображения. Есть что-то мистическое как в самом процессе, так и в подаче.
Любителям фотографии также нравятся черно-белые изображения. В их случае это волнение вызвано просмотром фотографий нашего мира в новом ракурсе — просто потому, что мы не видим их черно-белыми.
На самом деле, лучшие черно-белые фотографы тренируются «видеть» в черно-белом. Это навык, на приобретение которого могут уйти годы.
Существует множество атрибутов, которые могут способствовать созданию великолепной (и визуально захватывающей) черно-белой фотографии.
Однако… есть четыре «краеугольных» атрибута. Вот эти атрибуты:
- Контраст
- Текстура
- Тень
- Форма
это будет визуально стимулировать зрителей, которые его увидят.
Приведенная выше фотография мужчины и его собаки имеет все четыре атрибута. Сможете ли вы их заметить?
Я не говорю, что нет других необходимых атрибутов для создания удачной фотографии – будь то черно-белая или цветная. Очевидно, надо обращать внимание на освещение, сюжет, композицию и т. д.
Но, в случае удачных черно-белых фотографий, эти четыре атрибута являются общими знаменателями.
Сегодня поговорим о первом атрибуте. Давайте поговорим о контрасте.
Большинство из нас цифровые фотографы. В результате большинство из нас начинают процесс черно-белой фотографии с цветного файла. На самом деле, мы рекомендуем вам начать с цветного файла.
Не настраивайте камеру на черно-белую съемку.
Причина этой рекомендации заключается в том, что, делая это, вы передаете процесс преобразования черно-белого изображения автоматизированному программному обеспечению, а не используете свое творческое мышление для принятия решений.
Чтобы научиться видеть черно-белый контраст, вы должны понимать цветовой контраст.
На изображении выше три цвета, показанные в верхней половине, были преобразованы в черный и белый в нижней половине.
Что ты видишь? Они выглядят практически одинаково.
«Цветовой контраст» был недостаточно велик для того, чтобы эти три цвета преобразовались в черно-белые и дали замечательный результат.
Как вы боретесь с этой проблемой?
Сегодняшний краткий совет состоит из двух аспектов, и они конкретно касаются того, «как вы можете бороться с этой проблемой».
- Хорошая черно-белая фотография обычно получается при хорошем направленном освещении.
- Хорошее освещение помогает создать «цветовой контраст», создавая блики, тени и различные уровни яркости между ними.
Теперь… помните… у вас также есть некоторый контроль над тем, как цветное содержимое изображения будет преобразовано в черно-белое, при использовании вашего программного обеспечения во время этого преобразования. Но эта способность имеет ограничения.
Имея хорошее освещение с хорошим диапазоном цветового контраста, вы начинаете процесс преобразования с лучшей «основой» для работы.
Остальные три краеугольных атрибута мы рассмотрим в следующих кратких советах!
Если вы хотите точно узнать, как создавать самые лучшие черно-белые изображения, какие только можно сделать в эти выходные. Перейдите сюда, чтобы ознакомиться с нашим Better Black and White Premium Guide прямо сейчас »
Нажмите ниже, чтобы прочитать об этом на следующей странице…
СЛЕДУЩАЯ СТРАНИЦА
Перейти на следующую страницу »
О Кент Дюфолт
Кент Дюфолт стал фотографом в сентябре 1974 года. В старшей школе он прошел курс «Основы фотографии» и увлекся этим на всю жизнь. Его бестселлер Better Black & White помог тысячам фотографов во всем мире изучить и освоить искусство черно-белой фотографии.
Узнайте, как создавать собственные динамичные черно-белые изображения, которыми можно поделиться, не тратя денег на причудливые плагины или пресеты.
Это то, что все фотографы должны знать о черно-белой фотографии…
Узнайте больше здесь
Черно-белая фотография на продажу MA Andrew
MA Andrew
Продать черно-белые фотографииФото Нью-ЙоркаПродать фото ПарижаПродать фотографии ВенецииПродать фотографии БарбадосаПродать фотографии ГонконгаПродать фотографии МанчестерПродать архитектуру Хотите купить определенный принт? Поиск печати:
Черно-белая фотография на продажу из Нью-Йорка, Парижа, Лондона, Рио, Стамбула, Скай, Марракеша, Гонконга и др.Я продаю черно-белые фотографии на этом сайте уже более 20 лет. Черно-белая фотография — это запечатление одного момента во времени. Хитрость — часть, которая движет каждым фотографом — это попытка сбалансировать повествование со светом, композицией и идеальным временем. Без фотографов было бы меньше историй, меньше драмы, меньше воображения, и мир был бы более унылым местом. Использование черно-белой среды усложняет задачу. Теперь, как никогда ранее, фотограф должен учитывать эти ключевые моменты, иногда в мгновение ока, прежде чем открывать затвор. Это то, что меня заводит. Вот почему фотография и, тем более, черно-белая фотография — моя страсть. Я буду продолжать продавать черно-белые фотографии до тех пор, пока есть спрос.
М А Андрей, 2022
stpaulsdome
Купол собора Святого Павла. Лондон, 2007. Sigma SD10 50мм. Этот великолепный образец архитектуры был спроектирован сэром Кристофером Реном.
«Мудрость, накопленная с течением времени, я обнаружил, что каждый опыт является формой исследования»
Ансель Адамс
Галереи
Черно-белые репродукции на продажу
В разделе галерей вы найдете одну галерею с ограниченным тиражом. Помимо этой галереи, каждое изображение можно купить в виде печати на холсте или художественной фотографии. Холсты натянуты на прочные деревянные брусья и имеют толщину 1,5 дюйма. Вам останется только повесить готовое полотно. Каждая художественная фотография для продажи подписана, названа и датирована мной. Я продаю почти исключительно черно-белые фотографии. У меня есть две галереи, предлагающие цветную фотографию.
Заказать черно-белые фотографии
Просмотрите более 850 отпечатков, сделанных за более чем 20-летнюю карьеру. Каждый отпечаток доступен в виде произведения изобразительного искусства на тряпичной фотобумаге Hahnemuhle плотностью 308 г/м2 или в виде большого отпечатка на холсте. Заказывайте изображения с уверенностью.
Черно-белые репродукции фотографий
M A Эндрю продает черно-белые фотографии и изображения с 2002 года. Его работы появляются по всему миру, от гостиничных номеров Нью-Йорка до сингапурских закусочных и офисов.