Компьютерная обработка растровых изображений

 

Задание


Метод: Эквализация и получение требуемой (бимодальной) гистограммы яркости.

. Изучить алгоритм работы и особенности заданного метода обработки изображения.

. Разработать интерфейс и написать программу, реализующую данный метод, в форме Windows-приложения. Приложение должно обеспечивать:

ввод и отображение на дисплее монохромного изображения формата bmp;

максимально эффективную программную реализацию обработки заданным методом исходного изображения;

отображение результата обработки на экране дисплея и сохранение его в заданном пользователем файле;

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

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

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


1.Описание метода обработки «Выделение контурных линий» и особенностей его применения и программной реализации


Яркостные помехи могут существенно снижать различимость отдельных фрагментов изображения, но следует отметить, что для современных систем получения изображения в цифровом виде характерно практически полное отсутствие сколько-нибудь существенных яркостных помех. Однако полученные с их помощью изображения все же могут иметь недостаточную различимость отдельных фрагментов, что в основном обуславливается:

недостаточной контрастностью изображения, т.к. известно, что глаз человека не в состоянии различить границу между фрагментами, яркость которых отличается на одну - две градации;

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

Одной из главных характеристик качества изображения, позволяющих дать его статистическую оценку, является гистограмма яркости, представляющая собой графическое отображение функции Р(z), где значение Р(zi) - число пикселей яркости zi на всем изображении. Нормализованные гистограммы p(z), где


(N - число пикселей изображения),


позволяют сравнивать гистограммы изображений разных размеров. Причем значение p(zi) является оценкой вероятности того, что яркость случайно выбранного на изображении пикселя равна zi.


3.2 Увеличение контрастности


В большинстве методов увеличения контрастности растрового изображения яркость пикселя преобразованного изображения z'(x,y) зависит от яркости только соответствующего пикселя исходного изображения z(x,y), что позволяет перед обработкой сформировать массив соответствия яркостей в соответствии с заданным алгоритмом z'(x,y) = f(z). Такой массив значительно сокращает время обработки, т.к. после его формирования собственно обработка текущего пикселя исходного изображения сводится к присвоению соответствующему пикселю преобразованного изображения яркости, равной значению элемента массива с номером, равным яркости текущего пикселя исходного изображения.

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


(3.3)


где z, z' - яркость пикселя до и после преобразования, - минимальная яркость исходного изображения,

Сom - относительная контрастность изображения.

Из (3.3) видно, что существенное увеличение различимости фрагментов достигается только при низкой контрастности исходного изображения.

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

Нелинейное преобразование шкалы яркости или ее гамма-коррекция при Com близком к 1 позволяет увеличить контрастность в локальном диапазоне яркостей за счет снижения контрастности в других диапазонах. Например, с помощью степенного преобразования шкалы яркости

' = zm znom,(3.4)


где - относительная яркость. Если яркости пикселей исходного изображения занимают весь возможный диапазон, то zот изменяется в пределах 0…1. Значение n выбирается экспериментально, как правило, из диапазона n = 2…10, если известно, что плохо различимые фрагменты имеют высокую яркость, и n = 0,1…0,9, если плохо различимые фрагменты имеют низкую яркость.

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

' = 0,5zm(1 + (2zom - 1)n) для n > 1 нечетной степени.

Функция (3.5), описывающая данное преобразование при n>1 четной степени, является параболой, параметры которой подобраны так, чтобы z' = zm для z = 0,5zm. В результате преобразования пиксели, имеющие на исходном изображении яркость, симметричную относительно середины шкалы, приобретают одинаковую яркость. Таким образом, фрагменты, имеющие близкую яркость, как в темной, так и в светлой области шкалы, разносятся по шкале яркости на достаточное для увеличения их различимости расстояние, а фрагменты средней яркости приобретают яркость близкую к максимальной и частично сливаются.

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


.


В результате преобразования сохраняется средняя яркость изображения, а различимость темных и светлых фрагментов уменьшается. Аналогичные результаты можно получить, используя степенное преобразование со смещенным нулем для n < 1 нечетной степени.

Увеличение различимости фрагментов изображения можно получить и путем эквализации или выравнивания гистограммы, т.е. такого преобразования шкалы яркости, при котором гистограмма результирующего изображения будет приближаться по форме к равномерной. Метод основан на предположении, что наибольшая контрастность достигается на изображении, гистограмма которого представляет равномерное распределение пикселей по яркостям на всем диапазон (0 … 255). Преобразование шкалы яркости имеет вид


(3.6)


где z'i - значение элемента преобразованной шкалы яркости, соответствующее i -ой яркости исходной шкалы, p(zk) - нормализованная гистограмма яркости исходного изображения (i = 0 … 255).

В результате эквализации та часть гистограммы яркости исходного изображения, в которой соседние яркости имеют большие значения p(z), растягивается за счет слияния тех областей гистограммы, в которых соседние яркости имеют низкие значения p(z).

С помощью кумулятивных гистограмм можно так преобразовать изображение, чтобы его гистограмма имела требуемый вид. Кумулятивная (накопительная) гистограмма pс(zi) строится из нормализованной гистограммы



что с точностью до постоянного множителя zm совпадает с (3.6), причем pc(z) является монотонно возрастающей (неубывающей) функцией.

На первом этапе преобразования необходимо построить требуемую гистограмму и гистограмму обрабатываемого изображения, а также их кумулятивное представление p'c(z) и pc(z) соответственно. Для нахождения значений преобразованной шкалы яркости необходимо для каждой яркости zi найти соответствующее ей значение кумулятивной гистограммы обрабатываемого изображения pc(z), после чего найти равное ему значение p'c(z') на требуемой кумулятивной гистограмме. Соответствующее значение яркости z' и будет искомым, т.е. p'c(z') = pc(z).


2.Исходные тестовые и реальные изображения, результаты их обработки с дополнительной информацией


Рисунок 1 - Эквализация гистограммы серого градиента.


Рисунок 2 -Результат приведения гистограммы к бимодальной форме.


Рисунок 3 - Гистограммы цветного градиента.

Рисунок 4 - Результат приведения гистограммы к бимодальной форме.


Рисунок 5 - Эквализация гистограммы цветного изображения.


Рисунок 6 - Результат приведения гистограммы к бимодальной форме.


3. Код программы

Unit1;

Graphics, Windows, Messages, SysUtils, Variants, Classes, Controls, Forms,

Dialogs, ExtCtrls, StdCtrls, ComCtrls, ImgList, ToolWin, Menus, Jpeg, WinTypes, Math, Unit2;

TForm1 = class(TForm)

StatusBar1: TStatusBar;

GroupBox1: TGroupBox;

GroupBox2: TGroupBox;

Image1: TImage;

Image2: TImage;

ImageList1: TImageList;

ToolBar1: TToolBar;

ToolButton1: TToolButton;

ToolButton2: TToolButton;

ToolButton3: TToolButton;

PopupMenu1: TPopupMenu;

N1: TMenuItem;

N2: TMenuItem;

ToolButton5: TToolButton;

FileOpenDialog1: TFileOpenDialog;

ImageList2: TImageList;

procedure FormResize(Sender: TObject);

procedure ToolButton1Click(Sender: TObject);

procedure N1Click(Sender: TObject);

procedure N2Click(Sender: TObject);

procedure ToolButton3Click(Sender: TObject);

procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

procedure Image2MouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

private

{ Private declarations }

public

{ Public declarations }

end;

TRGBTripleArray = ARRAY[Word] of TRGBTriple;

pRGBTripleArray = ^TRGBTripleArray;= array[0..255] of integer;

TNormalHisto = array[0..255] of real;

function equalize(inBMP: Graphics.TBitmap; doUseAsYUV: boolean):Graphics.TBitmap;

function calcHisto(inBMP: Graphics.TBitmap):THisto;

function calcBimodalHisto():TNormalHisto;

function calcCumulativeHisto(histo: TNormalHisto):TNormalHisto;

function convertToBimodal(inBMP: Graphics.TBitmap; doUseAsYUV: boolean):Graphics.TBitmap;

function convertRGBToYUV(inBMP: Graphics.TBitmap):Graphics.TBitmap;

function convertYUVToRGB(inBMP: Graphics.TBitmap):Graphics.TBitmap;

function makeReplacementTable(size: Integer; histo: THisto):THisto;

function makeReplacementTableForTargetHisto(histo: TNormalHisto; target: TNormalHisto):THisto;

function normalizeHisto(size: Integer; histo: THisto):TNormalHisto;

Form1: TForm1;

srcBmp: Graphics.TBitmap;

dstBmp: Graphics.TBitmap;

sourceHisto: THisto;

gTargetHisto: THisto;

doUseRGB: boolean;

{$R *.dfm}TForm1.FormResize(Sender: TObject);

GroupBox1.Width := self.ClientWidth div 2;

GroupBox2.Width := self.ClientWidth div 2;;TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);

imageX, imageY, difX, difY: Integer;

lum: integer;

r,g,b: byte;

scan : pRGBTripleArray;

statusText: String;

difX:= (Image1.Width - Image1.Picture.Width) div 2;

difY:= (Image1.Height - Image1.Picture.Height) div 2;

imageX:= X - difX;

imageY:= Y - difY;

if((imageX>=0) and (imageY>=0)

and (imageX<Image1.Picture.Width) and (imageY<Image1.Picture.Height)) then

begin

scan:=Image1.Picture.Bitmap.ScanLine[imageY];

r := scan[imageX].rgbtRed;

g := scan[imageX].rgbtGreen;

b := scan[imageX].rgbtBlue;

lum := trunc((0.257*r) + (0.504*g) + (0.098*b) + 16 );

if(lum<0) then lum:=0;

if(lum>255) then lum:=255;

statusText:='X='+IntToStr(imageX) + ' Y='+ IntToStr(imageY);

statusText:=statusText+'; ';

statusText:=statusText+'R='+IntToStr(R) + ' G='+ IntToStr(G) + ' B='+ IntToStr(B);

statusText:=statusText+'; ';

statusText:=statusText+'Luminocity='+IntToStr(lum);

statusText:=statusText+';';

StatusBar1.SimpleText:= statusText;

end

else StatusBar1.SimpleText:='';;TForm1.Image2MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);

imageX, imageY, difX, difY: Integer;

lum: integer;

r,g,b: byte;

scan : pRGBTripleArray;

statusText: String;

difX:= (Image2.Width - Image2.Picture.Width) div 2;

difY:= (Image2.Height - Image2.Picture.Height) div 2;

imageX:= X - difX;

imageY:= Y - difY;

if((imageX>=0) and (imageY>=0)

and (imageX<Image2.Picture.Width) and (imageY<Image2.Picture.Height)) then

begin

scan:=Image2.Picture.Bitmap.ScanLine[imageY];

r := scan[imageX].rgbtRed;

g := scan[imageX].rgbtGreen;

b := scan[imageX].rgbtBlue;

lum := trunc((0.257*r) + (0.504*g) + (0.098*b) + 16 );

if(lum<0) then lum:=0;

if(lum>255) then lum:=255;

statusText:='X='+IntToStr(imageX) + ' Y='+ IntToStr(imageY);

statusText:=statusText+'; ';

statusText:=statusText+'R='+IntToStr(R) + ' G='+ IntToStr(G) + ' B='+ IntToStr(B);

statusText:=statusText+'; ';

statusText:=statusText+'Luminocity='+IntToStr(lum);

statusText:=statusText+';';

StatusBar1.SimpleText:= statusText;

end

else StatusBar1.SimpleText:='';;TForm1.N1Click(Sender: TObject);

i: Integer;

if(doUseRGB)

then dstBmp:=convertYUVToRGB(equalize(convertRGBToYUV(srcBmp),true))

else dstBmp:=equalize(srcBmp, false);

Image2.Picture.Assign(dstBmp);

gTargetHisto:= calcHisto(convertRGBToYUV(dstBmp));;

Form2.Chart1.Series[0].Clear;

Form2.Chart2.Series[0].Clear;

for i := 0 to 255 do.Chart1.Series[0].AddXY(i,sourceHisto[i]/(srcBmp.Height*srcBmp.Width),'');

for i := 0 to 255 do

Form2.Chart2.Series[0].AddXY(i,gTargetHisto[i]/(srcBmp.Height*srcBmp.Width),'');;TForm1.N2Click(Sender: TObject);

i: Integer;

if(doUseRGB)

then dstBmp:=convertYUVToRGB(convertToBimodal(convertRGBToYUV(srcBmp), true))

else dstBmp:=convertToBimodal(srcBmp, false);

Image2.Picture.Assign(dstBmp);

gTargetHisto:= calcHisto(convertRGBToYUV(dstBmp));;

Form2.Chart1.Series[0].Clear;

Form2.Chart2.Series[0].Clear;

for i := 0 to 255 do

Form2.Chart1.Series[0].AddXY(i,sourceHisto[i]/(srcBmp.Height*srcBmp.Width),'');

for i := 0 to 255 do

Form2.Chart2.Series[0].AddXY(i,gTargetHisto[i]/(srcBmp.Height*srcBmp.Width),'');;TForm1.ToolButton1Click(Sender: TObject);

image: TJPEGImage;

i, j: Integer;

pixel: TRGBTriple;

gray: byte;

scan : pRGBTripleArray;

if(FileOpenDialog1.Execute) then

begin

If(Application.MessageBox('Конвертировать в черно-бело изображение?','Настройка цвета', MB_YESNO)=IDNO)

then doUseRGB:=true

else doUseRGB:=false;

image := TJPEGImage.Create;

srcBmp := Graphics.TBitmap.Create;

dstBmp := Graphics.TBitmap.Create;

dstBmp.Assign(srcBmp);

image.LoadFromFile(FileOpenDialog1.FileName);

srcBmp.Assign(image);

if (not doUseRGB) then

begin

for i := 0 to srcBmp.Height-1 do

begin

scan:= srcBmp.ScanLine[i];

for j := 0 to srcBmp.Width-1 do

begin

pixel:= scan[j];

gray:= trunc(0.2989 * pixel.rgbtRed + 0.5870 * pixel.rgbtGreen + 0.1140 * pixel.rgbtBlue);

pixel.rgbtRed:= gray;

pixel.rgbtBlue:= gray;

pixel.rgbtGreen:= gray;

scan[j]:=pixel;

end;

end;

end;

if (not doUseRGB)

then sourceHisto := calcHisto(srcBmp)

else sourceHisto := calcHisto(convertRGBToYUV(srcBmp));

Image1.Picture.Assign(srcBmp);

Image2.Picture.Assign(dstBmp);

ToolButton3.Enabled:=true;

ToolButton5.Enabled:=true;

ToolButton5.EnableDropdown:=true;

end;;TForm1.ToolButton3Click(Sender: TObject);

i: integer;

Form2.Show();

gTargetHisto:= calcHisto(convertRGBToYUV(dstBmp));;

Form2.Chart1.Series[0].Clear;

Form2.Chart2.Series[0].Clear;

for i := 0 to 255 do.Chart1.Series[0].AddXY(i,sourceHisto[i]/(srcBmp.Height*srcBmp.Width),'');

for i := 0 to 255 do.Chart2.Series[0].AddXY(i,gTargetHisto[i]/(srcBmp.Height*srcBmp.Width),'');;equalize(inBMP: Graphics.TBitmap;doUseAsYUV: boolean):Graphics.TBitmap;

i, j: integer;

pixel: TRGBTriple;

gray: byte;

scan : pRGBTripleArray;

nTable: THisto;

outBMP:Graphics.TBitmap;

nTable:= makeReplacementTable(inBMP.Height*inBMP.Width, sourceHisto);

outBMP:=Graphics.TBitmap.Create();

outBMP.Assign(inBMP);

for i := 0 to outBMP.Height-1 do

begin

scan:= outBMP.ScanLine[i];

for j := 0 to outBMP.Width-1 do

begin

pixel:= scan[j];

gray:= nTable[pixel.rgbtRed];

pixel.rgbtRed:= gray;

if(not doUseAsYUV) then

begin

pixel.rgbtBlue:= gray;

pixel.rgbtGreen:= gray;

end;

scan[j]:=pixel;

end;

end;

Result:= outBMP;;calcBimodalHisto():TNormalHisto;

i: integer;

value: real;

step: real;

sum: real;

sum:=0;

value:=0;

step:=1/(128*64);i := 0 to 63 do

begin

Result[i]:=value;

sum:=sum+value;

value:=value+step;

end;

for i := 64 to 127 do

begin

Result[i]:=value;

sum:=sum+value;

value:=value-step;

end;

for i := 128 to 191 do

begin

Result[i]:=value;

sum:=sum+value;

value:=value+step;

end;

for i := 192 to 255 do

begin

Result[i]:=value;

sum:=sum+value;

value:=value-step;

end;;calcCumulativeHisto(histo: TNormalHisto):TNormalHisto;

sum: Real;

i, j: Integer;

for i := 0 to 255 do

begin

sum:=0;

for j := 0 to i do

sum:=sum+histo[j];

Result[i]:=sum;

end;;calcHisto(inBMP: Graphics.TBitmap):THisto;

i, j: integer;

pixel: TRGBTriple;

scan : pRGBTripleArray;

for i:= 0 to 255 do Result[i]:=0;

for i := 0 to inBMP.Height-1 do

begin

scan:= inBMP.ScanLine[i];

for j := 0 to inBMP.Width-1 do

begin

pixel:= scan[j];

Result[pixel.rgbtRed]:=Result[pixel.rgbtRed]+1;

end;

end;;convertRGBToYUV(inBMP: Graphics.TBitmap):Graphics.TBitmap;

i, j: integer;

r,g,b : Integer;

y,u,v:integer;

pixel: TRGBTriple;

scan : pRGBTripleArray;

outBMP: Graphics.TBitmap;

outBMP:=Graphics.TBitmap.Create();

outBMP.Assign(inBMP);

for i := 0 to outBMP.Height-1 do

begin

scan:= outBMP.ScanLine[i];

for j := 0 to outBMP.Width-1 do

begin

pixel:= scan[j];

r:= pixel.rgbtRed;

g:= pixel.rgbtGreen;

b:= pixel.rgbtBlue;

Y:=trunc((0.257 * R) + (0.504 * G) + (0.098 * B) + 16 );

V:=trunc((0.439 * R) - (0.368 * G) - (0.071 * B) + 128);

U:=trunc(-(0.148 * R) - (0.291 * G) + (0.439 * B) + 128);

if(y>255) then y:=255;

if(y<0) then y:=0;

if(u>255) then u:=255;

if(u<0) then u:=0;

if(v>255) then v:=255;

if(v<0) then v:=0;

pixel.rgbtRed := y;

pixel.rgbtGreen := u;

pixel.rgbtBlue := v;

scan[j]:=pixel;

end;

end;

Result:=outBMP;;convertYUVToRGB(inBMP: Graphics.TBitmap):Graphics.TBitmap;

i, j: integer;

y,u,v:integer;

r,g,b:integer;

pixel: TRGBTriple;

scan : pRGBTripleArray;

outBMP: Graphics.TBitmap;

outBMP:=Graphics.TBitmap.Create();

outBMP.Assign(inBMP);

for i := 0 to outBMP.Height-1 do

begin

scan:= outBMP.ScanLine[i];

for j := 0 to outBMP.Width-1 do

begin

pixel:= scan[j];

y:= pixel.rgbtRed;

u := pixel.rgbtGreen;

v := pixel.rgbtBlue;

B:= trunc(1.164*(Y - 16) + 2.018*(U - 128));

G:= trunc(1.164*(Y - 16) - 0.813*(V - 128) - 0.391*(U - 128));

R:= trunc(1.164*(Y - 16) + 1.596*(V - 128));

if(r>255) then r:=255;

if(r<0) then r:=0;

if(g>255) then g:=255;

if(g<0) then g:=0;

if(b>255) then b:=255;

if(b<0) then b:=0;

pixel.rgbtRed := r;

pixel.rgbtGreen := g;

pixel.rgbtBlue :=b;

scan[j]:=pixel;

end;

end;

Result:=outBMP;;convertToBimodal(inBMP: Graphics.TBitmap; doUseAsYUV: boolean):Graphics.TBitmap;

normalSourceHisto, normalTargetHisto: TNormalHisto;

cumulativeSourceHisto, cumulativeTargetHisto: TNormalHisto;

repTable: THisto;

newBMP: Graphics.TBitmap;

i, j: integer;

pixel: TRGBTriple;

scan : pRGBTripleArray;

gray: byte;

normalSourceHisto:=normalizeHisto(inBMP.Height*inBMP.Width, sourceHisto);

normalTargetHisto:=calcBimodalHisto();

cumulativeSourceHisto:=calcCumulativeHisto(normalSourceHisto);

cumulativeTargetHisto:= calcCumulativeHisto(normalTargetHisto);

repTable:= makeReplacementTableForTargetHisto(cumulativeSourceHisto, cumulativeTargetHisto);

newBMP:=Graphics.TBitmap.Create();

newBMP.Assign(inBMP);

for i := 0 to newBMP.Height-1 do

begin

scan:= newBMP.ScanLine[i];

for j := 0 to newBMP.Width-1 do

begin

pixel:= scan[j];

gray:= repTable[pixel.rgbtRed];

pixel.rgbtRed:= gray;

if(not doUseAsYUV) then

begin

pixel.rgbtBlue:= gray;

pixel.rgbtGreen:= gray;

end;

scan[j]:=pixel;

end;

end;


Выводы

растровый изображение программный компьютерный

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

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


Задание Метод: Эквализация и получение требуемой (бимодальной) гистограммы яркости. . Изучить алгоритм работы и особенности заданного метода обработки

Больше работ по теме:

КОНТАКТНЫЙ EMAIL: [email protected]

Скачать реферат © 2017 | Пользовательское соглашение

Скачать      Реферат

ПРОФЕССИОНАЛЬНАЯ ПОМОЩЬ СТУДЕНТАМ