Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
1 / 1 / 1
Регистрация: 16.04.2009
Сообщений: 26
1

Гауссово размывание растра.

19.03.2012, 11:10. Показов 1250. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
unit GBlur2;
 
interface
 
uses Windows, Graphics;
 
type
 
  PRGBTriple = ^TRGBTriple;
  TRGBTriple = packed record
    b: byte; //легче для использования чем типа rgbtBlue...
    g: byte;
    r: byte;
  end;
 
  PRow = ^TRow;
  TRow = array[0..1000000] of TRGBTriple;
 
  PPRows = ^TPRows;
  TPRows = array[0..1000000] of PRow;
 
const
  MaxKernelSize = 100;
 
type
 
  TKernelSize = 1..MaxKernelSize;
 
  TKernel = record
    Size: TKernelSize;
    Weights: array[-MaxKernelSize..MaxKernelSize] of single;
  end;
  //идея заключается в том, что при использовании TKernel мы игнорируем
  //Weights (вес), за исключением Weights в диапазоне -Size..Size.
 
procedure GBlur(theBitmap: TBitmap; radius: double);
 
implementation
 
uses SysUtils;
 
procedure MakeGaussianKernel(var K: TKernel; radius: double;
 
  MaxData, DataGranularity: double);
//Делаем K (гауссово зерно) со среднеквадратичным отклонением = radius.
//Для текущего приложения мы устанавливаем переменные MaxData = 255,
//DataGranularity = 1. Теперь в процедуре установим значение
//K.Size так, что при использовании K мы будем игнорировать Weights (вес)
//с наименее возможными значениями. (Малый размер нам на пользу,
//поскольку время выполнения напрямую зависит от
//значения K.Size.)
var
  j: integer;
  temp, delta: double;
  KernelSize: TKernelSize;
begin
 
  for j := Low(K.Weights) to High(K.Weights) do
  begin
    temp := j / radius;
    K.Weights[j] := exp(-temp * temp / 2);
  end;
 
  //делаем так, чтобы sum(Weights) = 1:
 
  temp := 0;
  for j := Low(K.Weights) to High(K.Weights) do
    temp := temp + K.Weights[j];
  for j := Low(K.Weights) to High(K.Weights) do
    K.Weights[j] := K.Weights[j] / temp;
 
  //теперь отбрасываем (или делаем отметку "игнорировать"
  //для переменной Size) данные, имеющие относительно небольшое значение -
  //это важно, в противном случае смазавание происходим с малым радиусом и
  //той области, которая "захватывается" большим радиусом...
 
  KernelSize := MaxKernelSize;
  delta := DataGranularity / (2 * MaxData);
  temp := 0;
  while (temp < delta) and (KernelSize > 1) do
  begin
    temp := temp + 2 * K.Weights[KernelSize];
    dec(KernelSize);
  end;
 
  K.Size := KernelSize;
 
  //теперь для корректности возвращаемого результата проводим ту же
  //операцию с K.Size, так, чтобы сумма всех данных была равна единице:
 
  temp := 0;
  for j := -K.Size to K.Size do
    temp := temp + K.Weights[j];
  for j := -K.Size to K.Size do
    K.Weights[j] := K.Weights[j] / temp;
 
end;
 
function TrimInt(Lower, Upper, theInteger: integer): integer;
begin
 
  if (theInteger <= Upper) and (theInteger >= Lower) then
    result := theInteger
  else if theInteger > Upper then
    result := Upper
  else
    result := Lower;
end;
 
function TrimReal(Lower, Upper: integer; x: double): integer;
begin
 
  if (x < upper) and (x >= lower) then
    result := trunc(x)
  else if x > Upper then
    result := Upper
  else
    result := Lower;
end;
 
procedure BlurRow(var theRow: array of TRGBTriple; K: TKernel; P: PRow);
var
  j, n, LocalRow: integer;
  tr, tg, tb: double; //tempRed и др.
 
  w: double;
begin
 
  for j := 0 to High(theRow) do
 
  begin
    tb := 0;
    tg := 0;
    tr := 0;
    for n := -K.Size to K.Size do
    begin
      w := K.Weights[n];
 
      //TrimInt задает отступ от края строки...
 
      with theRow[TrimInt(0, High(theRow), j - n)] do
      begin
        tb := tb + w * b;
        tg := tg + w * g;
        tr := tr + w * r;
      end;
    end;
    with P[j] do
    begin
      b := TrimReal(0, 255, tb);
      g := TrimReal(0, 255, tg);
      r := TrimReal(0, 255, tr);
    end;
  end;
 
  Move(P[0], theRow[0], (High(theRow) + 1) * Sizeof(TRGBTriple));
end;
 
procedure GBlur(theBitmap: TBitmap; radius: double);
var
  Row, Col: integer;
  theRows: PPRows;
  K: TKernel;
  ACol: PRow;
  P: PRow;
begin
  if (theBitmap.HandleType <> bmDIB) or (theBitmap.PixelFormat <> pf24Bit) then
 
    raise
      exception.Create('GBlur может работать только с 24-битными изображениями');
 
  MakeGaussianKernel(K, radius, 255, 1);
  GetMem(theRows, theBitmap.Height * SizeOf(PRow));
  GetMem(ACol, theBitmap.Height * SizeOf(TRGBTriple));
 
  //запись позиции данных изображения:
  for Row := 0 to theBitmap.Height - 1 do
 
    theRows[Row] := theBitmap.Scanline[Row];
 
  //размываем каждую строчку:
  P := AllocMem(theBitmap.Width * SizeOf(TRGBTriple));
  for Row := 0 to theBitmap.Height - 1 do
 
    BlurRow(Slice(theRows[Row]^, theBitmap.Width), K, P);
 
  //теперь размываем каждую колонку
  ReAllocMem(P, theBitmap.Height * SizeOf(TRGBTriple));
  for Col := 0 to theBitmap.Width - 1 do
  begin
    //- считываем первую колонку в TRow:
 
    for Row := 0 to theBitmap.Height - 1 do
      ACol[Row] := theRows[Row][Col];
 
    BlurRow(Slice(ACol^, theBitmap.Height), K, P);
 
    //теперь помещаем обработанный столбец на свое место в данные изображения:
 
    for Row := 0 to theBitmap.Height - 1 do
      theRows[Row][Col] := ACol[Row];
  end;
 
  FreeMem(theRows);
  FreeMem(ACol);
  ReAllocMem(P, 0);
end;
 
end.
 
 
Должно работать, если только вы не удалите некоторый код вместе с глупыми коментариями. Для примера:
 
 
procedure TForm1.Button1Click(Sender: TObject);
var
  b: TBitmap;
begin
  if not openDialog1.Execute then
    exit;
 
  b := TBitmap.Create;
  b.LoadFromFile(OpenDialog1.Filename);
  b.PixelFormat := pf24Bit;
  Canvas.Draw(0, 0, b);
  GBlur(b, StrToFloat(Edit1.text));
  Canvas.Draw(b.Width, 0, b);
  b.Free;
end;
Подскажите пожалуйста что тут не хватает для запуска. всё испробовал ни что не получается... Зарание большое спасибо
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.03.2012, 11:10
Ответы с готовыми решениями:

Гауссово размытие
Всем привет! Прошу помощи в поиске готового решения в виде размытия гаусса... Требуется найти такой...

Гауссово сглаживание в PictureBox
Гауссово сглаживание (http://en.wikipedia.org/wiki/Gaussian_blur). Команда «Apply blur» применяет...

Гауссово распределение и построение графика. Проверка кода
Добрый вечер! Товарищи помогите с написанием программы для Гауссова распределения и построения...

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

7
2184 / 1254 / 143
Регистрация: 28.04.2010
Сообщений: 4,592
19.03.2012, 11:28 2
Цитата Сообщение от Nicola Посмотреть сообщение
Подскажите пожалуйста что тут не хватает для запуска
все хватает, все работает замечательно
0
Почетный модератор
64300 / 47595 / 32743
Регистрация: 18.05.2008
Сообщений: 115,181
19.03.2012, 11:30 3
Создать модуль GBlur2.dcu текст которого приведен и программу.
Вложения
Тип файла: rar Гауссово размывание растра.rar (8.2 Кб, 26 просмотров)
0
2184 / 1254 / 143
Регистрация: 28.04.2010
Сообщений: 4,592
19.03.2012, 11:31 4
Цитата Сообщение от Puporev Посмотреть сообщение
Создать модуль GBlur2.dcu
достаточно сделать отдельный юнит и подключить его к своей программе
0
1 / 1 / 1
Регистрация: 16.04.2009
Сообщений: 26
19.03.2012, 11:31  [ТС] 5
Если вам не трудно можете прислать исходник это кода. За ранее благодарен вам!
0
2184 / 1254 / 143
Регистрация: 28.04.2010
Сообщений: 4,592
19.03.2012, 11:33 6
Цитата Сообщение от Nicola Посмотреть сообщение
прислать исходник это кода
исходник кода это как прикажете понимать? в асму что ли перевести код? )))
код что ты выложил выше рабочий, ничего дополнительного не нужно, только твоя внимательность
0
Почетный модератор
64300 / 47595 / 32743
Регистрация: 18.05.2008
Сообщений: 115,181
19.03.2012, 11:35 7
Nicola, Ты проект во вложении не смотрел? А кому тогда я делал, мне он и нафиг не нужен.
А исходный код ты сам выложил.
0
1 / 1 / 1
Регистрация: 16.04.2009
Сообщений: 26
20.03.2012, 18:14  [ТС] 8
Всё увидел.. Большое спасибо

Добавлено через 1 минуту
Подскажите пожалуйста как сюда вставит кнопку сохранить...)) За ранее большое вам спасибо!
0
20.03.2012, 18:14
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.03.2012, 18:14
Помогаю со студенческими работами здесь

Изображение ТВ растра для чересстрочной развертки
Изобразить телевизионный растр для чересстрочной развертки при заданном количестве элементов в...

Corel Draw перевод из растра в вектор
Здравствуйте, есть ли программы перевода растра в вектор(чтобы не очень коряво было)? Или же такое...

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

Вывод растра с заменой выбранного цвета на зеленый
Добрый день, мне требуется сделать замену выбранного цвета на растре ( через ColorDialog ) , на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru