Книга программиста/Фильтрация изображений на PascalABC.Net
Внешний вид
(перенаправлено с «Фильтрация изображений на PascalABC.Net»)
К оглавлению | Назад | Вперёд
Все программы, код которых выложен здесь, являются работоспособными. На момент написания программ использовалась среда PascalABC.Net 3.0.
Комментарии к программам
[править]- FilterMatrix - матрица, которая позволяет по разному обрабатывать изображение.
- Pic2 - результирующее изображение.
Изменение яркости
[править]Формулы |
---|
r = Round(c.R + 128 * N / 100) |
g = Round(c.G + 128 * N / 100) |
b = Round(c.B + 128 * N / 100) |
Комментарии к коду
- N - процент изменения яркости
uses GraphABC;
const
N = -50;
var
Pic1: Picture;
V: real := 128 * N / 100;
procedure TruncColor(var a: integer);
begin
if a > 255 then a := 255 else
if a < 0 then a := 0;
end;
begin
Pic1 := new Picture('C:\Asya\pine-nuts.jpg');
SetWindowIsFixedSize(true);
SetWindowSize(Pic1.Width, Pic1.Height);
CenterWindow();
for var i := 0 to Pic1.Width - 1 do
for var j := 0 to Pic1.Height - 1 do
begin
var c := Pic1.GetPixel(i, j);
var r := Round(c.R + V);
var g := Round(c.G + V);
var b := Round(c.B + V);
TruncColor(r);
TruncColor(g);
TruncColor(b);
Pic1.PutPixel(i, j, RGB(r, g, b));
end;
Pic1.Draw(0, 0);
end.
Инвертирование изображения
[править]Стандартный вариант
[править]Формулы |
---|
r = 255 - c.R |
g = 255 - c.G |
b = 255 - c.B |
uses GraphABC;
var
Pic1: Picture;
begin
Pic1 := new Picture('C:\asya\pine-nuts.jpg');
SetWindowIsFixedSize(true);
SetWindowSize(Pic1.Width, Pic1.Height);
CenterWindow();
for var i := 0 to Pic1.Width - 1 do
for var j := 0 to Pic1.Height - 1 do
begin
var c := Pic1.GetPixel(i, j);
Pic1.PutPixel(i, j, RGB(255 - c.R, 255 - c.G, 255 - c.B));
end;
Pic1.Draw(0, 0);
end.
Усложненный вариант
[править]Комментарии к коду
- FactorA - фактор интерполяции компоненты прозрачности между изначальным цветом и противоположным
- FactorR - фактор интерполяции красной компоненты между изначальным цветом и противоположным
- FactorG - фактор интерполяции зеленой компоненты между изначальным цветом и противоположным
- FactorB - фактор интерполяции синей компоненты между изначальным цветом и противоположным
uses GraphABC;
const
FactorA = 100;
FactorR = 10;
FactorG = 0;
FactorB = 40;
var
Pic1: Picture;
//Выполняет интерполяцию между числовыми значениями.
function ByteInterpolation(a, b, p: byte) := Round(a + (b - a) * p / 100);
//Выполняет интерполяцию цвета.
function InterpolateColor(с1, с2: Color; pA, pR, pG, pB: byte) := ARGB(ByteInterpolation(с1.A, с2.A, pA), ByteInterpolation(с1.R, с2.R, pR), ByteInterpolation(с1.G, с2.G, pG), ByteInterpolation(с1.B, с2.B, pB));
begin
Pic1 := new Picture('C:\Ilya\pine-nuts.jpg');
SetWindowIsFixedSize(true);
SetWindowSize(Pic1.Width, Pic1.Height);
CenterWindow();
for var i := 0 to Pic1.Width - 1 do
for var j := 0 to Pic1.Height - 1 do
begin
var с := Pic1.GetPixel(i, j);
var r := 255 - с.R;
var g := 255 - с.G;
var b := 255 - с.B;
Pic1.PutPixel(i, j, InterpolateColor(с, RGB(r, g, b), FactorA, FactorR, FactorG, FactorB));
end;
Pic1.Draw(0, 0);
end.
P. S. Для интерполяции между числами можно так же использовать:
function Interpolation(a, b, p: integer) := Round(a + (b - a) * p / 100);
Оконтуривание
[править]uses GraphABC;
var
Pic1, Pic2: Picture;
FilterMatrix: array [0..2, 0..2] of real;
S: real;
R, G, B: real;
procedure TruncColor(var a: integer);
begin
if a > 255 then a := 255 else
if a < 0 then a := 0;
end;
begin
Pic1 := new Picture('C:\Ilya\MjcVeXIf.jpg');
SetWindowIsFixedSize(true);
SetWindowSize(Pic1.Width, Pic1.Height);
CenterWindow();
Pic2 := new Picture(Pic1.Width, Pic1.Height);
for var i := 1 to Pic1.Width - 2 do
for var j := 1 to Pic1.Height - 2 do
Pic2.PutPixel(i, j, Pic1.GetPixel(i, j));
FilterMatrix[0, 0] := 1;FilterMatrix[0, 1] := 0;FilterMatrix[0, 2] := 1;
FilterMatrix[1, 0] := 0;FilterMatrix[1, 1] := -4;FilterMatrix[1, 2] := 0;
FilterMatrix[2, 0] := 1;FilterMatrix[2, 1] := 0;FilterMatrix[2, 2] := 1;
LockDrawing();
for var i := 1 to Pic1.Width - 2 do
for var j := 1 to Pic1.Height - 2 do
begin
for var i2 := i - 1 to i + 1 do
for var j2 := j - 1 to j + 1 do
begin
var m := FilterMatrix[i2 - (i - 1), j2 - (j - 1)];
var c := Pic1.GetPixel(i2, j2);
R := R + c.R * m;
G := G + c.G * m;
B := B + c.B * m;
S := S + m;
end;
if S = 0 then S := 1;
var rR := Round(R / S);
var rG := Round(G / S);
var rB := Round(B / S);
TruncColor(rR);
TruncColor(rG);
TruncColor(rB);
Pic2.PutPixel(i, j, RGB(rR, rG, rB));
R := 0;
G := 0;
B := 0;
S := 0;
end;
Pic2.Draw();
Redraw();
end.
Преобразование в нецветное изображение
[править]Формулы |
---|
r = Round((c.R + c.G + c.B) / 3) |
g = Round((c.R + c.G + c.B) / 3) |
b = Round((c.R + c.G + c.B) / 3) |
uses GraphABC;
var
Pic1: Picture;
begin
Pic1 := new Picture('C:\Ilya\pine-nuts.jpg');
SetWindowIsFixedSize(true);
SetWindowSize(Pic1.Width, Pic1.Height);
CenterWindow();
for var i := 0 to Pic1.Width - 1 do
for var j := 0 to Pic1.Height - 1 do
begin
var c := Pic1.GetPixel(i, j);
var cRGB := Round((c.R + c.G + c.B) / 3);
Pic1.PutPixel(i, j, RGB(cRGB, cRGB, cRGB));
end;
Pic1.Draw(0, 0);
end.
Размытие
[править]uses GraphABC;
var
Pic1, Pic2: Picture;
FilterMatrix: array [0..2, 0..2] of real;
S: real;
R, G, B: real;
procedure TruncColor(var a: integer);
begin
if a > 255 then a := 255 else
if a < 0 then a := 0;
end;
begin
Pic1 := new Picture('C:\Ilya\MjcVeXIf.jpg');
SetWindowIsFixedSize(true);
SetWindowSize(Pic1.Width, Pic1.Height);
CenterWindow();
Pic2 := new Picture(Pic1.Width, Pic1.Height);
for var i := 1 to Pic1.Width - 2 do
for var j := 1 to Pic1.Height - 2 do
Pic2.PutPixel(i, j, Pic1.GetPixel(i, j));
FilterMatrix[0, 0] := 1; FilterMatrix[0, 1] := 1; FilterMatrix[0, 2] := 1;
FilterMatrix[1, 0] := 1; FilterMatrix[1, 1] := 1; FilterMatrix[1, 2] := 1;
FilterMatrix[2, 0] := 1; FilterMatrix[2, 1] := 1; FilterMatrix[2, 2] := 1;
LockDrawing();
for var i := 1 to Pic1.Width - 2 do
for var j := 1 to Pic1.Height - 2 do
begin
for var i2 := i - 1 to i + 1 do
for var j2 := j - 1 to j + 1 do
begin
var m := FilterMatrix[i2 - (i - 1), j2 - (j - 1)];
var c := Pic1.GetPixel(i2, j2);
R := R + c.R * m;
G := G + c.G * m;
B := B + c.B * m;
S := S + m;
end;
if S = 0 then S := 1;
var rR := Round(R / S);
var rG := Round(G / S);
var rB := Round(B / S);
TruncColor(rR);
TruncColor(rG);
TruncColor(rB);
Pic2.PutPixel(i, j, RGB(rR, rG, rB));
R := 0;
G := 0;
B := 0;
S := 0;
end;
Pic2.Draw();
Redraw();
end.
Сепия
[править]Комментарии к коду
- R - фактор интерполяции красной компоненты между изначальным цветом и серым
- G - фактор интерполяции зеленой компоненты между изначальным цветом и серым
- B - фактор интерполяции синей компоненты между изначальным цветом и серым
- Intensivity - интенсивность цвета
uses GraphABC;
const
R = 85;
G = 50;
B = 0;
Intensivity = 40;
var
Pic1: Picture;
function ByteInterpolation(a, b, p: byte) := Round(a + (b - a) * p / 100);
function InterpolateColor(с1, с2: Color; p: byte) := ARGB(ByteInterpolation(с1.A, с2.A, p), ByteInterpolation(с1.R, с2.R, p), ByteInterpolation(с1.G, с2.G, p), ByteInterpolation(с1.B, с2.B, p));
begin
Pic1 := new Picture('C:\Ilya\MjcVeXIf.jpg');
SetWindowIsFixedSize(true);
SetWindowSize(Pic1.Width, Pic1.Height);
CenterWindow();
for var i := 0 to Pic1.Width - 1 do
for var j := 0 to Pic1.Height - 1 do
begin
var c := Pic1.GetPixel(i, j);
var gray := Round((c.R + c.G + c.B) / 3);
Pic1.PutPixel(i, j, InterpolateColor(RGB(gray, gray, gray), RGB(R, G, B), Intensivity));
end;
Pic1.Draw(0, 0);
end.
Тонирование изображения
[править]uses GraphABC;
const
R = 100;
G = 0;
B = 0;
Intensivity = 50;
var
Pic1: Picture;
function ByteInterpolation(a, b, p: byte) := Round(a + (b - a) * p / 100);
function InterpolateColor(с1, с2: Color; p: byte):= ARGB(ByteInterpolation(с1.A, с2.A, p), ByteInterpolation(с1.R, с2.R, p), ByteInterpolation(с1.G, с2.G, p), ByteInterpolation(с1.B, с2.B, p));
begin
Pic1 := new Picture('C:\Ilya\pine-nuts.jpg');
SetWindowIsFixedSize(true);
SetWindowSize(Pic1.Width, Pic1.Height);
CenterWindow();
for var i := 0 to Pic1.Width - 1 do
for var j := 0 to Pic1.Height - 1 do
begin
var c := Pic1.GetPixel(i, j);
var gray := Round((c.R + c.G + c.B) / 3);
Pic1.PutPixel(i, j, InterpolateColor(RGB(gray, gray, gray), RGB(R, G, B), Intensivity));
end;
Pic1.Draw(0, 0);
end.
Изменение контраста
[править]Увеличение контраста
[править]Формулы |
---|
r = Round((c.R * 100 - 128 * N) / (100 - N)) |
g = Round((c.G * 100 - 128 * N) / (100 - N)) |
b = Round((c.B * 100 - 128 * N) / (100 - N)) |
uses GraphABC;
const
N = 99;
var
Pic1: Picture;
procedure TruncColor(var a: integer);
begin
if a > 255 then a := 255 else
if a < 0 then a := 0;
end;
begin
Pic1 := new Picture('C:\Ilya\MjcVeXIf.jpg');
SetWindowIsFixedSize(true);
SetWindowSize(Pic1.Width, Pic1.Height);
CenterWindow();
for var i := 1 to Pic1.Width - 1 do
for var j := 1 to Pic1.Height - 1 do
begin
var c := Pic1.GetPixel(i, j);
var a := 128 * N;
var p := 100 - N;
var r := Round((c.R * 100 - a) / p);
var g := Round((c.G * 100 - a) / p);
var b := Round((c.B * 100 - a) / p);
TruncColor(r);
TruncColor(g);
TruncColor(b);
Pic1.PutPixel(i, j, RGB(r, g, b));
end;
LockDrawing();
Pic1.Draw();
Redraw();
end.
uses GraphABC;
const
N = 3.0;
var
Pic1: Picture;
Rm, Gm, Bm: integer;
procedure TruncColor(var a: integer);
begin
if a > 255 then a := 255 else
if a < 0 then a := 0;
end;
begin
Pic1 := new Picture('C:\Ilya\MjcVeXIf.jpg');
SetWindowIsFixedSize(true);
SetWindowSize(Pic1.Width, Pic1.Height);
CenterWindow();
for var i := 1 to Pic1.Width - 1 do
for var j := 1 to Pic1.Height - 1 do
begin
var c := Pic1.GetPixel(i, j);
Inc(Rm, c.R);
Inc(Gm, c.G);
Inc(Bm, c.B);
end;
var S := Pic1.Width * Pic1.Height;
Rm := Round(Rm / S);
Gm := Round(Gm / S);
Bm := Round(Bm / S);
for var i := 1 to Pic1.Width - 1 do
for var j := 1 to Pic1.Height - 1 do
begin
var c := Pic1.GetPixel(i, j);
var dR := Round((c.R - Rm) * N);
var dG := Round((c.G - Gm) * N);
var dB := Round((c.B - Bm) * N);
var r := Rm + dR;
var g := Gm + dG;
var b := Bm + dB;
TruncColor(r);
TruncColor(g);
TruncColor(b);
Pic1.PutPixel(i, j, RGB(r, g, b));
end;
LockDrawing();
Pic1.Draw();
Redraw();
end.
Уменьшение контраста
[править]Формулы |
---|
r = Round((c.R * (100 - N) + 128 * N) / 100) |
g = Round((c.G * (100 - N) + 128 * N) / 100) |
b = Round((c.B * (100 - N) + 128 * N) / 100) |
uses GraphABC;
const
N = 90;
var
Pic1: Picture;
procedure TruncColor(var a: integer);
begin
if a > 255 then a := 255 else
if a < 0 then a := 0;
end;
begin
Pic1 := new Picture('C:\Ilya\MjcVeXIf.jpg');
SetWindowIsFixedSize(true);
SetWindowSize(Pic1.Width, Pic1.Height);
CenterWindow();
for var i := 1 to Pic1.Width - 1 do
for var j := 1 to Pic1.Height - 1 do
begin
var c := Pic1.GetPixel(i, j);
var a := 128 * N;
var p := 100 - N;
var r := Round((c.R * p + a) / 100);
var g := Round((c.G * p + a) / 100);
var b := Round((c.B * p + a) / 100);
TruncColor(r);
TruncColor(g);
TruncColor(b);
Pic1.PutPixel(i, j, RGB(r, g, b));
end;
LockDrawing();
Pic1.Draw();
Redraw();
end.
Увеличение резкости
[править]uses GraphABC;
var
Pic1, Pic2: Picture;
FilterMatrix: array [0..2, 0..2] of real;
S: real;
R, G, B: real;
procedure TruncColor(var a: integer);
begin
if a > 255 then a := 255 else
if a < 0 then a := 0;
end;
begin
Pic1 := new Picture('C:\Ilya\MjcVeXIf.jpg');
SetWindowIsFixedSize(true);
SetWindowSize(Pic1.Width, Pic1.Height);
CenterWindow();
Pic2 := new Picture(Pic1.Width, Pic1.Height);
for var i := 1 to Pic1.Width - 2 do
for var j := 1 to Pic1.Height - 2 do
Pic2.PutPixel(i, j, Pic1.GetPixel(i, j));
FilterMatrix[0, 0] := -1; FilterMatrix[0, 1] := -1; FilterMatrix[0, 2] := -1;
FilterMatrix[1, 0] := -1; FilterMatrix[1, 1] := 9; FilterMatrix[1, 2] := -1;
FilterMatrix[2, 0] := -1; FilterMatrix[2, 1] := -1; FilterMatrix[2, 2] := -1;
LockDrawing();
for var i := 1 to Pic1.Width - 2 do
for var j := 1 to Pic1.Height - 2 do
begin
for var i2 := i - 1 to i + 1 do
for var j2 := j - 1 to j + 1 do
begin
var m := FilterMatrix[i2 - (i - 1), j2 - (j - 1)];
var c := Pic1.GetPixel(i2, j2);
R := R + c.R * m;
G := G + c.G * m;
B := B + c.B * m;
S := S + m;
end;
if S = 0 then S := 1;
var rR := Round(R / S);
var rG := Round(G / S);
var rB := Round(B / S);
TruncColor(rR);
TruncColor(rG);
TruncColor(rB);
Pic2.PutPixel(i, j, RGB(rR, rG, rB));
R := 0;
G := 0;
B := 0;
S := 0;
end;
Pic2.Draw();
Redraw();
end.
Изменение цветового баланса
[править]Формулы |
---|
r = Round(c.R + 128 * NR / 100) |
g = Round(c.G + 128 * NG / 100) |
b = Round(c.B + 128 * NB / 100) |
Комментарии к коду
- NR - процент изменения красной компоненты цвета
- NG - процент изменения зеленой компоненты цвета
- NB - процент изменения синей компоненты цвета
uses GraphABC;
const
NR = 100;
NG = 1;
NB = 1;
var
Pic1: Picture;
procedure TruncColor(var a: integer);
begin
if a > 255 then a := 255 else
if a < 0 then a := 0;
end;
begin
Pic1 := new Picture('C:\Ilya\MjcVeXIf.jpg');
SetWindowIsFixedSize(true);
SetWindowSize(Pic1.Width, Pic1.Height);
CenterWindow();
for var i := 1 to Pic1.Width - 1 do
for var j := 1 to Pic1.Height - 1 do
begin
var c := Pic1.GetPixel(i, j);
var r := Round(c.R + 128 * NR / 100);
var g := Round(c.G + 128 * NG / 100);
var b := Round(c.B + 128 * NB / 100);
TruncColor(r);
TruncColor(g);
TruncColor(b);
Pic1.PutPixel(i, j, RGB(r, g, b));
end;
LockDrawing();
Pic1.Draw();
Redraw();
end.