Опубликован: 08.07.2007 | Доступ: свободный | Студентов: 1432 / 183 | Оценка: 4.43 / 4.02 | Длительность: 13:47:00
Специальности: Программист
Лекция 8:

Использование шейдеров с помощью языка HLSL. Графический процессор

Ниже на рисунке приведены три гистограммы интенсивности различного класса.


Гистограмма слева определяет изображения, в которых мало пикселей черного и белого цветов (низкоконтрастные изображения). Гистограмма посередине соответствует изображениям, в которых число черных и белых пикселей значительно превышает все остальные (высококонтрастные изображения). И гистограмма справа представляет изображения, в которых количество пикселей с различными интенсивностями цветов приблизительно одинаково (нормальноконтрастные изображения). Изменение контраста в изображении можно осуществить с помощью линейных преобразований. Для гистограмм, соответствующих низкоконтрастным изображениям, выделяют отрезок [Q1,Q2], на котором сосредоточена значительная часть интенсивностей. Затем данный отрезок [Q1,Q2] линейно отражают в отрезок [0…255] с помощью следующего преобразования: I(x,y)= 255*(I(x,y)-Q1)/(Q2-Q1). Аналогично можно получить формулу для уменьшения контраста в изображении. В этом случае преобразование будет иметь следующий вид: I(x,y)= R1+I(x,y)*(R2-R1)/255, где [R1,R2] – некий отрезок, в который отображается все множество значений интенсивностей. Графически операции увеличения и уменьшения контрастности в изображении можно представить следующим образом.


Негативное преобразование инвертирует значения интенсивностей яркости так, что темные пиксели становятся светлыми и наоборот. Математически это задается довольно простой формулой:

I(x,y)= 255- I(x,y), а графически это выглядит следующим образом.


Пороговое отсечение (бинаризация) преобразует изображение в оттенках серого в изображение, в котором присутствует всего два цвета, как правило, белый и черный (бинарное). На языке формул бинаризация имеет такой вид: I(x,y)=0, если I(x,y)>p ; I(x,y)=255, если I(x,y)<p, где p – некоторый заданный порог. Графически операция порогового отсечения задается следующим образом.

Очень часто пороговое отсечение применяется как промежуточный шаг в задачах распознавания изображений для устранения ошибок сканирования и оцифровки.

Получение изображения в оттенках серого из цветного также можно отнести к точечным процессам. Каждый пиксель цветного изображения представляет собой тройку байт, значения которых соответствуют весам красного, зеленого и синего цветов. Это так называемая цветовая модель RGB (Red, Green, Blue). Преобразование цветного изображения в оттенки серого осуществляется по следующей формуле:

I=0.3*R+0.59*G+0.11*B, где Iзначение интенсивности серого цвета, R, G, B - значения весов красного, зеленого и синего цветов соответственно.

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

sampler tex0;

struct PS_INPUT
{
  float2 base : TEXCOORD0;
};
struct PS_OUTPUT
{
  float4 diffuse : COLOR0;
};
PS_OUTPUT Main (PS_INPUT input)
{
  PS_OUTPUT output;
  float4 col = tex2D(tex0, input.base);
  ...
  return output;
};
Исходное изображение

Приведение к оттенкам серого цвета
float4 col = tex2D(tex0, input.base);
float4 lum = float4(0.3, 0.59, 0.11, 0);
output.diffuse = dot(lum,col);

Увеличение яркости
float4 col = tex2D(tex0, input.base);
float4 lum = float4(0.3, 0.59, 0.11, 0);
output.diffuse = dot(lum,col)+0.2f;

Уменьшение яркости
float4 col = tex2D(tex0, input.base);
float4 lum = float4(0.3, 0.59, 0.11, 0);
output.diffuse = dot(lum,col)-0.2f;

Увеличение контраста
float4 col = tex2D(tex0, input.base);
  float4 lum = float4(0.3, 0.59, 0.11, 0);
  float gray = dot(lum,col);
  float Q1 = 0.2f;  float Q2 = 0.7f;
  if (gray > Q2) gray = 1.0f;
  else if (gray < Q1) gray = 0.0f;
  else gray = (gray - Q1)/(Q2-Q1);
  output.diffuse = gray;

Уменьшение контраста
float4 col = tex2D(tex0, input.base);
  float4 lum = float4(0.3, 0.59, 0.11, 0);
  float gray = dot(lum,col);
  float R1 = 0.2f;  float R2 = 0.7f;
  gray = R1+gray*(R2-R1);
  output.diffuse = gray;

Пороговое отсечение (бинаризация)
float4 col = tex2D(tex0, input.base);
  float4 lum = float4(0.3, 0.59, 0.11, 0);
  float gray = dot(lum,col);
  float p = 0.4f;
  if (gray > p) gray = 1.0f;
  else if (gray < p) gray = 0.0f;
  output.diffuse = gray;

Негативное преобразование
float4 col = tex2D(tex0, input.base);
  float4 lum = float4(0.3, 0.59, 0.11, 0);
  float gray = dot(lum,col);
  output.diffuse = 1.0f-gray;