- •Краскова Надежда Иннокентьевна
- •Повышение разрешающей способности изображений
- •Содержание:
- •Глава I. Обзор и сравнительный анализ методов и алгоритмов повышения разрешения изображений………………………………..5
- •Глава II. Проектная часть. Описание технологии выполнения……19
- •Введение
- •Глава I. Обзор и сравнительный анализ методов и алгоритмов повышения разрешения изображений
- •Анализ исследуемой проблемы
- •Расчет коэффициентов
- •Сравнительная оценка существующих программ, повышающих разрешение изображений
- •Глава II. Проектная часть. Описание технологии выполнения работы
- •2.1. Выбор оптимального инструментария для разработки
- •2.2. Разработка логической схемы и реализация алгоритма
- •2.2.1. Форма поиска файлов
- •2.2.2. Форма преобразования изображений
- •Кнопка «Преобразование»
- •Кнопка «Сохранить»
- •Меню «Файл» Элемент Меню «Файл» - подменю «Параметры страницы»
- •Элемент Меню «Файл» - подменю «Вывод на печать»
- •Элемент Меню «Файл» - подменю «Закрыть»
- •2.2.3. Реализация алгоритмов интерполяции
- •Заключение
- •Список использованной литературы
Меню «Файл» Элемент Меню «Файл» - подменю «Параметры страницы»
procedure TForm3.N10Click(Sender: TObject);
begin
PageSetupDialog1.Execute;
end;
Вызывает диалоговое окно «Параметры страницы» через компонент PageSetupDialog.
Элемент Меню «Файл» - подменю «Вывод на печать»
procedure TForm3.N9Click(Sender: TObject);
var
relheight, relwidth: integer;
koef: real;
begin
if printDialog1.Execute then
begin
//Печать изображения
with Printer do
begin
BeginDoc;
koef:=image1.Picture.Height/image1.Picture.Width;
Canvas.StretchDraw(Rect(0,0,PageWidth,Round(PageWidth*koef)), Image1.Picture.Graphic);
…
Вызывает диалоговое окно «Печать» через компонент PrintDialog.
Элемент Меню «Файл» - подменю «Закрыть»
procedure TForm3.N4Click(Sender: TObject);
begin
close;
end;
Процедура закрывает форму «Преобразования изображений».
2.2.3. Реализация алгоритмов интерполяции
Фрагмент кода алгоритма билинейной интерполяции:
function interpolate(bm: tbitmap; dx, dy: single):TBitmap;
var
bm1: tbitmap;
z1, z2: single;
k, k1, k2: single;
x1, y1: integer;
c: array [0..1, 0..1, 0..2] of byte;
res: array [0..2] of byte;
x, y: integer;
xp, yp: integer;
xo, yo: integer;
col: integer;
pix: tcolor;
begin
bm1 := tbitmap.create;
bm1.width := round(bm.width * dx);
bm1.height := round(bm.height * dy);
for y := 0 to bm1.height - 1 do begin
for x := 0 to bm1.width - 1 do begin
xo := trunc(x / dx);
yo := trunc(y / dy);
x1 := round(xo * dx);
y1 := round(yo * dy);
for yp := 0 to 1 do
for xp := 0 to 1 do begin
pix := bm.canvas.pixels[xo + xp, yo + yp];
c[xp, yp, 0] := getrvalue(pix);
c[xp, yp, 1] := getgvalue(pix);
c[xp, yp, 2] := getbvalue(pix);
end;
for col := 0 to 2 do begin
k1 := (c[1,0,col] - c[0,0,col]) / dx;
z1 := x * k1 + c[0,0,col] - x1 * k1;
k2 := (c[1,1,col] - c[0,1,col]) / dx;
z2 := x * k2 + c[0,1,col] - x1 * k2;
k := (z2 - z1) / dy;
res[col] := round(y * k + z1 - y1 * k);
end;
bm1.canvas.pixels[x,y] := rgb(res[0], res[1], res[2]);
end;
Form3.Caption := IntToStr(round(100 * y / bm1.Height)) + '%';
Application.ProcessMessages;
if Application.Terminated then
Exit;
end;
bm := bm1;
interpolate:=bm1;
end;
…
Изображение рассматривается как поверхность, цвет - третье измерение. Если изображение цветное, то интерполяция проводится отдельно для трех цветов.
Для каждой точки нового изображения с координатами (xo,yo) нужно найти четыре ближайшие точки исходного изображения. Эти точки образуют квадрат. Через две верхние точки проводится прямая f1(x), через две нижние - f2(x). Дальше находятся координаты для точек f1(xo) и f2(xo), через которые проводится третья прямая f3(y). Цвет искомой точки - это f3(yo).
Этот алгоритм хорошо работает при целых или больших коэффициентах увеличения.
Но резкие границы размываются. Для уменьшения изображения этот алгоритм также не подходит.
Фрагмент кода алгоритма бикубической интерполяции:
…
Begin
bmp1:=TBitmap.Create; bmp1.Width:=bmp.Width;bmp1.Height:=bmp.height;
//------------------------------------------------------------------------
For j:=0 to bmp.Height do //Преобразование только по горизонтали
begin
For i:=0 to Round(bmp.Width/2) do
begin
i_new:=(i*2); //по номеру пикселя i в новом (формируемом) изображении находим номер i_new в исходном изображении
dx:=0.5;//Это смещение (сдвиг) весовой функции
R:=0; G:=0; B:=0; s:=0;
For k:=-1 to 2 do//яркость пикселя с номером i равна сумме яркостей этого пикселя, соседа слева и двух соседей справа, умноженных на весовые коэффициенты
Begin
S:=i_new+k;//Это просто для удобства
If s<0 then s:=0; If s>bmp.Width-1 then s:=bmp.Width-1;
R:=R+GetRValue(bmp.Canvas.Pixels[(s),j])*fR(k-dx);
G:=G+GetGValue(bmp.Canvas.Pixels[(s),j])*fR(k-dx);
B:=B+GetBValue(bmp.Canvas.Pixels[(s),j])*fR(k-dx);
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;
End;
//В выходном изображении дублируем каждый второй столбец
bmp1.Canvas.Pixels[i*2,j]:=RGB(Round(R),Round(G),Round(B));
bmp1.Canvas.Pixels[i*2+1,j]:=RGB(Round(R),Round(G),Round(B));
end;{For i}
Form3.Caption := IntToStr(round(100 * j/ bmp.Height)) + '%';
Application.ProcessMessages;
if Application.Terminated then
Exit;
end;
…
Яркость пикселя нового изображения находится как сумма яркостей соответствующего пикселя старого изображения и трех его соседей (один сосед слева и два - справа), умноженных на значения весовой функции.
Чтобы новое изображение не сжималось по горизонтали в два раза, я его расширяла методом ближайшего соседа - три строки в конце подпрограммы.
Экспериментальным путем подобраны коэффициенты весовой функции. Если разрешить использовать подобранные коэффициенты, то бикубическая интерполяция получается максимально похожей как в Фотошопе.
Выводы к главе II:
В этой главе приведено общее описание технологии выполнения разработки. В первом параграфе главы приведены описания инструментария для разработки, основных использованных компонентов. Во втором параграфе главы построена логическая схема разрабатываемого продукта – пошаговое описание технологии выполнения.