2014-12-13 5 views
0

Я пишу программу на C#, но надеюсь, что C++ и C# в фоновом режиме точно так же. Что я хочу - возьму серое изображение и отдельные цвета над 127 и под 17 для разделения изображений. Если я просто получить «белый» цвет и программным образом растянуть их из диапазона (127-255) до (0-255), какImageMagick - Установить уровни для изображения в градациях серого

// pseudocode 
int min = 127, max = 255; 
for(int x; x< width; x++) 
    pixels[x] = pixels[x]/(max-min) * max; 

Тогда здесь будет не гладкий промежуток .. Я имею в виду, что 127 преобразуется в 0 но 128 конвертирует до 2 и цветов 1,3,5, ... не существует.

То есть исходное изображение с альфа: image original

То есть изображение с «экстрагируют белый»: image original

То есть изображение с «черным» извлеченной: snorgg.ru/patchwork/tst_black.png.

Я не ясно понять, как он может быть реализован так exampe код понравится:

{ 
    im.MagickImage image = new im.MagickImage("c:/55/11.png"); 
    im.MagickImage imageWhite = ExtractWhite(image); 
    im.MagickImage imageBlack = ExtractBlack(image); 
} 

.... 

public static im.MagickImage ExtractWhite(im.MagickImage img){ 

    im.MagickImage result = new im.MagickImage(img); 

    ????? 
    ????? 

    return result; 
} 

thankы заранее))

+0

Я нахожу ваш вопрос трудно понять. Если вы начинаете с одного изображения, имеющего 1 максимум iuxel и ширину 256 пикселей, первый пиксель равен 0, а затем 1, 2, 3 ... 255, сколько выходных изображений будет и что будет в каждом? –

+0

@Mark Setchell, будет два изображения. Если «середина серая» справа в середине, то: сначала «0,0, 2, 2, 4, 4, ... 255, 255'. И то же самое - '0,0, 2, 2, 4, 4, ... 255, 255'. Если «середина серого» в 1/4 от 255 (между четвертью и другими кварталами), то: «Первые» 0,0, 0, 0, 4, 4, 4, 4, ... 255, 255'. И далее - '0,1, 2, 2, 4, 5,6,6, 8, ... 254, 255'. Из-за попытки растянуть 0..63 до 0..255. – user3444737

ответ

0

Я думаю, что ваш расчет не так. Вы вводите в заблуждение диапазон ввода с выходным диапазоном. Входные диапазоны варьируются от min до max, а диапазон выходных сигналов - от 0 до 255. Это совпадение, что ваш вход max равен вашему максимальному выходу (255).

Если вы хотите, чтобы растянуть значение в диапазоне min ... max (= диапазон входного сигнала) для 0 ... 255 (= выходного диапазона), а затем вычислить этот

int brightness = pixel[x]; 
if (brightness <= min) { 
    pixel[x] = 0; 
} else if (brightness >= max) { 
    pixel[x] = 255; 
} else { 
    pixel[x] = 255 * (brightness - min)/(max - min); 
} 

Где min >= 0 и max <= 255 и min < max.

Сначала вы должны убедиться, что яркость находится в диапазоне min ... max, в противном случае ваш результат будет превышать диапазон 0 ... 255. После этого вы также можете ограничить диапазон выходных данных, но в любом случае вы должны сделать проверку диапазона.

Затем вычитайте min из яркости. Теперь у вас есть значение от 0 до (max-min). При делении на (max-min) вы получаете значение от 0 до 1. Умножьте результат на 255, и вы получите значение в желаемом диапазоне 0 ... 255.

Также вы должны знать о том, что вы выполняете целочисленную арифметику. Поэтому сначала умножьте на 255, а затем разделите. Если вы начинаете с деления, вы получаете либо 0, либо 1 как промежуточный результат (поскольку целочисленная арифметика не дает десятичных знаков, а конечный результат будет равен 0 или 255, а все серые тона будут потеряны.

+0

Да, ты прав.Значение должно быть перемещено на нулевой уровень: 'класса Program \t { \t \t статических INT Calc (интермедиат Вэл, внутр мин, Int макс) \t \t { \t \t \t возвращения (INT) (((поплавок) Вал - мин)/(max - min) * max); \t \t} \t \t статической силы основных (String [] арг) \t \t { \t \t \t INT = 127 мин, макс = 255; \t \t \t int bgn = 127, mdl = 200, end = 255; \t \t \t Debug.WriteLine («Ожидаемый 0, Got -» + Calc (bgn, min, max) .ToString()); \t \t \t Debug.WriteLine ("Ожидаемый ~ 150, Got -" + Calc (mdl, min, max) .ToString()); \t \t Debug.WriteLine («Ожидаемый 255, Got -» + Calc (end, min, max) .ToString()); \t \t} \t} '' Ожидаемая 0, Got - 0 Ожидаемое ~ 150, Got - 145 Ожидаемое 255, Got - 255' – user3444737

+0

Но это не там, где я стека (( – user3444737

+0

Там, кажется, метод делая это 'void BrightnessContrast (Процентная яркость, Контраст в процентах);'. Также существует метод WritablePixelCollection GetWritablePixels(); ', возвращающий пиксели, которые вы можете изменить самостоятельно. –

0

Эффект, который вы видите banding или posterisation.Это обусловлено тем, что контрастные растяжки передаются на данные, которые не отбираются с достаточной глубиной. Поскольку у вас есть только 8-битные данные, у вас есть только 255 уровней серого. Если вы растянете 50 уровней между 100-150 в диапазоне от 255 уровней будут иметь место пробелы в вашей гистограмме в пределах 5 уровней. Решение состоит в том, чтобы получить 16-битные данные или сделать менее резкие изменения контраста.

В качестве альтернативы, если я, как я, вы являются фотографом и более заинтересованы в Эстетичность изображения, чем его научная точность, вы можете добавить небольшое количество случайных шумов для маскировки и «размазать» полосу ...

Есть хорошее описание here.

Я также могу показать вам пример с ImageMagick, сначала мы создаем два полутоновых пандусы (градиенты), один 8-битный и один 16-бит, как в диапазоне от уровня яркости от 100 до 150, как это:

convert -depth 8 -size 100x500 gradient:"rgb(100,100,100)-rgb(150,150,150)" -rotate 90 gradient8.png 

convert -depth 16 -size 100x500 gradient:"rgb(100,100,100)-rgb(150,150,150)" -rotate 90 gradient16.png 

Они выглядят так:

enter image description here enter image description here

Если я теперь растягивать их обоих в полном диапазоне 0-255 вы сразу увидите эффект полосатости в 8-битной версии, и Smoo thness от 16-битной версии - которая, кстати, является причиной для использования RAW формата (12-14 бит) на вашей камере, а не съемки 8-битные изображения в формате JPEG:

convert gradient8.png -auto-level out8.png 
convert gradient16.png -auto-level out16.png 

enter image description here enter image description here

Я упомянул, используя шум валовой видимости эффекта полосатости, и вы можете сделать это с помощью метода так:

convert out8.png -attenuate 0.3 +noise gaussian out.png 

, который дает вам менее выраженный эффект, несколько похоже на фильм зерна:

enter image description here

Я не уверен точно, что вы пытаетесь сделать, но если вы просто хотите, чтобы распространить уровни яркости от 127-255 по всему диапазону 0-255, вы можете сделать это просто в командной строки, как это:

convert orig.png -level 50%,100% whites.png 

enter image description here

Аналогично, если вы хотите, чтобы уровень яркости от 0-17 распространения в диапазоне 0-255, вы можете сделать

convert orig.png -level 0,6.66667% blacks.png 

enter image description here