![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Оптимизация кода
Вова © (2013-06-25 20:17:00)
Страницы: < 1 2 3 4 5 6 7 8 9 10 11 >
Есть процедура задачей которой является приведения пикселя любого цвета к цвету одного из диапазонов. Но скорость ее работы огорчает меня, можно ли ее как нибудь ускорить?
function almostEqual(a, b: byte): Boolean;
begin
if ABS(a - b) < 10 then
result := true
else
result := false;
end;
Function ConvertColorToRGBColorMap(color: LongInt; ColSel: String = 'None')
: TColorWithName;
var
RGBV: trgbcolor;
begin
RGBV.red := color;
RGBV.green := color shr 8;
RGBV.blue := color shr 16;
with RGBV do
if almostEqual(red, green) and almostEqual(red, blue) and
almostEqual(blue, green) then // тогда это серый или черный или белый
begin
if almostEqual(red, 255) then // белый
begin
result.color := RGB(255, 255, 255);
result.Name := 'White';
end
else if red > 120 then
begin
result.color := RGB(190, 190, 190);
result.Name := 'LightGray';
end
else if (red > 92) then // темно серый
begin
result.color := RGB(100, 100, 100);
result.Name := 'DarkGray';
end
else
begin
result.color := RGB(0, 0, 0);
result.Name := 'Black';
end // черный
end
else
begin
if (red < green) and (red < blue) and almostEqual(green, blue) and
(blue > 130) then
begin
result.color := RGB(0, 0, 255);
result.Name := 'Blue';
end // result:= rgb(0,255,255)//голубой
else if (green < red) and (green < blue) and almostEqual(red, blue) and
(red > 130) then
begin
result.color := RGB(255, 0, 255);
result.Name := 'Pink';
end // розовый
else if (blue < green) and (blue < red) and almostEqual(green, red) and
(green > 130) then
begin
result.color := RGB(255, 255, 0);
result.Name := 'Yellow';
end // желтый
else if (red > green) and (red > blue) and (red > 130) then
begin
result.color := RGB(255, 0, 0);
result.Name := 'Red';
end // красный
else if (blue > green) and (blue > red) and (blue > 130) then
begin
result.color := RGB(0, 0, 255);
result.Name := 'Blue';
end // синий
else if (green > blue) and (green > red) and (green > 130) then
begin
result.color := RGB(0, 255, 0);
result.Name := 'Green';
end // зеленый
else
begin
result.color := RGB(0, 0, 0);
result.Name := 'Black';
end
end;
if not (ColSel = 'None') then
if not (ColSel = Result.Name) then
begin
result.color := RGB(255, 255, 255);
result.Name := 'White'; //Если выборка только по одному цвету, то
//все остальные цвета переводим в белый
end
else
begin
result.color := RGB(0, 0, 0);
result.Name := 'Black'; //Если выборка только по одному цвету, то
//этот цвет переводим в черный
end
end;
Sha (2013-06-28 15:34:00) [181]> Вова (28.06.13 15:10) [26]
В качестве домашнего задания можешь написать инициализацию таблицы для случая ColSel<>'None'.
И со сдвигами разберешься и польза для работы опять же.
Sha (2013-06-28 15:23:00) [182]> приоритет and выше, чем у shr
у меня вроде одинаковый)
Sha (2013-06-28 15:17:00) [183]Последнюю строчку в InitColorMap спиши из [25] - и будет тебе щастье без черного цвета.
Ты специально тормозишь программу???
Выкинь нафиг вторую функцию. Просто бери элемент массива в нужном месте программы.
А уж если когда понадобится название цвета, тогда вызывай хоть черта с рогами.
MBo (2013-06-28 15:17:00) [184]Я бы так скобками обложил:
(Color shr 12) and $F0F or Color and $F0
причина - приоритет and выше, чем у shr
или для читабельности (и при паранойе) вообще так:
((Color shr 12) and $F0F) or (Color and $F0)
Вова (2013-06-28 15:10:00) [185]
TColorMap = array[0..16*16*16-1] of TColorWithName;
var
ColorMap:TColorMap;
Procedure InitColorMap();
var
i, j, k: byte;
begin
for i := 0 to 15 do
for j := 0 to 15 do
for k := 0 to 15 do
ColorMap[i * 256 + 16 * k + j] := ConvertColorToRGBColorMap
((i * 256 * 256 + j * 256 + k) * 16);
end;
Function FindConvertedColor(color: LongInt; ColSel: String = 'None')
: TColorWithName;
begin
result := ColorMap[color shr 12 and $F0F or color and $F0];
if not(ColSel = 'None') then
if not(ColSel = result.Name) then
begin
result := ColorMap[0];
end
else
begin
result := ColorMap[Length(ColorMap)-1];
end;
end;
Sha (2013-06-28 15:06:00) [186]Максимальный цвет получается при r=g=b=240 т.к. 4 младших бита обнуляются при инициализации. Для этого цвета твоя функция должна вернуть белый.
Или второй способ - установить эти биты при инициализации, например так:
for i:=0 to 15 do for j:=0 to 15 do for k:=0 to 15 do ColorMap[i*256+16*k+j]:=YourSuperFunc((i*16+15)*256*256+(j*16+15)*256+(k*16+15));
Sha (2013-06-28 14:55:00) [187]не верю, код давай
Вова (2013-06-28 14:54:00) [188]
> ничего этого (разбивать и понимать) не требуется1. просто
> объяви таблицу для хранения вычисленных результатовvar
> ColorMap: array[0..16*16*16-1] of integer;2. заранее помести
> результаты вызова любой своей функции для 4k цветов в таблицу
> (см.[12])3. когда требуется, вместо вызова своей функции
> бери результат из таблицы (см.[7])
я так и делал, и обнаружил что в инициализированном массиве белого цвета нет ( а если я ищу в массиве белый цвет, то он мне возвращает светлосерый.
Sha (2013-06-28 14:47:00) [189]ничего этого (разбивать и понимать) не требуется
1. просто объяви таблицу для хранения вычисленных результатов
var
ColorMap: array[0..16*16*16-1] of integer;
2. заранее помести результаты вызова любой своей функции для 4k цветов в таблицу (см.[12])
3. когда требуется, вместо вызова своей функции бери результат из таблицы (см.[7])
MBo (2013-06-28 14:39:00) [190]>RGBV.red := color;
>RGBV.green := color shr 8;
>RGBV.blue := color shr 16;
После каждой из этих операций наложи маску $FF для выделения млвдшего байта
(color shr 8) and $FF
>я в этих сдвигах битов ничего не понимать
так разберись, пригодится
Вот, например:
http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=838
Вова (2013-06-28 14:38:00) [191]Color shr 12 and $F0F or Color and $F0 - как это расшифровать, что это значит?)
Вова (2013-06-28 14:05:00) [192]Вообщем после преобразования такого Color shr 12 and $F0F or Color and $F0
разбиение на RGB такого вида:
RGBV.red := color;
RGBV.green := color shr 8;
RGBV.blue := color shr 16;
на выходе дает лажу ( как то например белый превращается в красный
беда в том что я в этих сдвигах битов ничего не понимать, помогите.
Вова (2013-06-28 13:28:00) [193]эх, только вот обнаружилось, что белого при такой инициализации нет в массиве (
Во всяком случае цвет 255 255 255 получается в результате светло серым.
Вова (2013-06-27 14:49:00) [194]ща сделал как Sha написал - скорость стала как у порогового, может даж немного быстрее. if then - конкретно тормозят, даже если одно условие вставить то уже +30 милисекунд на картинку (
Jeer (2013-06-27 12:33:00) [195]Да, адаптивное - рулит.
Когда-то было надо, сделал свой вариант:
Константный threshold:
http://s018.radikal.ru/i503/1306/11/a134e2eddde4.jpg
Адаптивный threshold:
http://s14.radikal.ru/i187/1306/2a/8325f2f04dd5.jpg
Sapersky (2013-06-27 11:26:00) [196]пороговое преобразование работает в данном случае ненадежно, т.к. яркость фона непостоянна
http://locv.ru/wiki/5.7.1_Адаптивное_пороговое_преобразование
Sha (2013-06-27 09:58:00) [197]в варианте [7,12] перенастройка выполняется аналогично инициализации,
только производится вызов другой YourSuperFunc2 или той же, но с другими параметрами
han_malign (2013-06-27 09:34:00) [198]
> на разных картинках диапазоны цветов приводящие к желаемому результату могут быть разные
- для уменьшения глубины цвета(квантизации) - используется обычно октантное дерево...
У Фень Юаня есть есть описание алгоритма, и здесь -
http://www.efg2.com/Lab/Graphics/Colors/ShowDemoOne.htm
Sha (2013-06-26 11:11:00) [199]Нет не так, а вот так:
for i:=0 to 15 do for j:=0 to 15 do for k:=0 to 15 do ColorMap[i*256+16*k+j]:=YourSuperFunc((i*256*256+j*256+k)*16);
Sha (2013-06-26 11:09:00) [200]Инициализация выглядит так:
for i:=0 to 15 do for j:=0 to 15 do for k:=0 to 15 do ColorMap[i*256+16*k+j]:=YourSuperFunc(i*256*256+j*256+k);