Россия, г. Кострома |
Использование шейдеров с помощью языка 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; |