Инструкции для разработки классов для [закрытого] внедрения зависимости

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

Увеличение значения экспозиции (EV) на 1 соответствует удвоению экспозиции. Экспозиция - это линейная мера количества света, которое достигает каждого пикселя. Удвоение экспозиции удваивает количество света. Поскольку в фотографии обычно думают о долях текущей экспозиции, имеет смысл говорить об «увеличении EV на 1», а не о «умножении экспозиции на 2».

Таким образом, действительно, чтобы увеличить значение экспозиции на n , умножьте значения пикселей на 2 n sup>.

Если входное изображение представляет собой файл JPEG или TIFF, скорее всего, оно находится в цветовом пространстве sRGB. Это нелинейное цветовое пространство, предназначенное для увеличения видимого диапазона файла 8-битного изображения. Прежде чем изменять экспозицию, необходимо сначала преобразовать sRGB в линейный RGB. Это может быть достигнуто приблизительно путем увеличения значения каждого пикселя до степени 2,2, Википедия имеет точную формулировку .


Проблемы в ОП вызваны неточным уровнем черного. raw.black_level_per_channel возвращает 528 для данного изображения (это одинаковое значение для каждого из каналов, хотя я полагаю, что это не обязательно имеет место для других моделей камер), а не 512. Кроме того, код записывает raw.raw_image_visible обратно в [113 ], что не правильно.

Следующий код дает правильные результаты:

import rawpy
import numpy as np
from PIL import Image

bit_depth = 12
exposure = 5

path = "/001_ev0.DNG"
raw = rawpy.imread(path)
black_level = raw.black_level_per_channel[0] # assume they're all the same

im = raw.raw_image
im = np.maximum(im, black_level) - black_level # changed order of computation
im *= 2**exposure
im = im + black_level
im = np.minimum(im, 2**12 - 1)
raw.raw_image[:,:] = im
im = raw.postprocess(use_camera_wb=True, no_auto_bright=True)
img = Image.fromarray(im, 'RGB')
img.show()

6
задан Community 23 May 2017 в 11:59
поделиться

1 ответ

Важная вещь состоит в том, чтобы попытаться кодировать к интерфейсам, и Ваших классов принимают экземпляры тех интерфейсов, а не создают сами экземпляры. Можно, очевидно, сойти с ума с этим, но это - общая хорошая практика независимо от поблочного тестирования или DI.

Например, если у Вас есть Объект Доступа к данным, Вы могли бы быть склонны записать основу для всех ДАО как это:

public class BaseDAO
{
    public BaseDAO(String connectionURL, 
                   String driverName, 
                   String username, String password)
    {
        // use them to create a connection via JDBC, e.g.
    }

    protected Connection getConnection() { return connection; }
}

Однако было бы лучше удалить это из класса в пользу интерфейса

public interface DatabaseConnection
{
    Connection getConnection();
}

public class BaseDAO
{
    public BaseDAO(DatabaseConnection dbConnection)
    {
        this.dbConnection = dbConnection;
    }

    protected Connection getConnection() { return dbConnection.getConnection(); }
}

Теперь, можно обеспечить multilple реализации DatabaseConnection. Даже игнорируя поблочное тестирование, если мы предполагаем, что используем JDBC, существует два способа получить a Connection : пул соединения от контейнера, или непосредственно через использование драйвера. Теперь, Ваш код ДАО не связан ни с одной стратегией.

Для тестирования можно сделать a MockDatabaseConnection это соединяется с некоторыми, встроил реализацию JDBC с консервированными данными для тестирования кода.

1
ответ дан 17 December 2019 в 22:15
поделиться
Другие вопросы по тегам:

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