Форум: "Начинающим";
Текущий архив: 2014.07.06;
Скачать: [xml.tar.bz2];
ВнизОптимизация кода Найти похожие ветки
← →
Вова (2013-06-25 20:17) [0]Есть процедура задачей которой является приведения пикселя любого цвета к цвету одного из диапазонов. Но скорость ее работы огорчает меня, можно ли ее как нибудь ускорить?
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-25 21:22) [1]этот алгоритм был дан свыше сразу в таком виде, или ему предшествовало какое-то описание?
← →
RWolf © (2013-06-25 23:14) [2]
> можно ли ее как нибудь ускорить?
выкинуть всё, связанное со строками.
возвращать только получившийся цвет или код диапазона.
← →
Вова (2013-06-26 06:09) [3]он не был дан свыше я его накалякал сам )
а что тут описывать?
смотрим в каком диапазоне цвет и приводим цвет к значению конца этого диапазона
← →
Sha © (2013-06-26 08:06) [4]> я его накалякал сам )
О том, и речь, что одному описанию могут соответствовать несколько разных алгоритмов.
И совершенно непонятно, почему надо оптимизировать именно этот вариант алгоритма.
Не говоря уже о том, что можно выбрать другие константы и правила сравнения.
И, наконец, что-то там с голубым напутано.
← →
Вова (2013-06-26 09:50) [5]эм, а какой вариант оптимизирвать? у меня только один есть...
голубой поначалу был голубым, но потом я решил что он тоже будет синим, так что так и задумано
можно изменить через tbmp.PixelFormat := pf8bit; количество цветов но все же это не то что нужно, картинка после этого выглядит неудобо варимой, а свой алгоритм можно еще и поднастроить под конкретную ситуацию (ну вот как я захотел и убрал голубой)
← →
Sha © (2013-06-26 09:54) [6]> эм, а какой вариант оптимизирвать? у меня только один есть...
ты б задачу описал, может другие варианты и появились бы )
а то получается, спрашиваешь, в мешке какого цвета лучше бегать стометровку
← →
Sha © (2013-06-26 10:20) [7]например, вот такой вариант:
Color:=ColorMap[Color shr 12 and $F0F or Color and $F0];
← →
Вова (2013-06-26 10:37) [8]Задача взять TBitmap 24 битный и поменять в нем цвета каждого пикселя. т.e. в картинке все цвета должны преобразоваться к: Белому, Светлосерому, Темносерому,черному, синему,красному, зеленому, розовому, желтому.
делается это для того чтобы четко выделить объекты на картинке, например, буквы светлосерые, но на 24 битном изображении это куча разных значений цветов. пороговое преобразование работает в данном случае ненадежно, т.к. яркость фона непостоянна (т.е. определять границы объектов по разцице яркостей), но зато оно работает в 2 раза быстрее этого алгоритма ( несмотря на то что я всю картинку раз 5 прохожу пороговым, а этим всего 1 )
т.е. я могу сказать что после фильтрации на картинке должен остаться только светлосерый цвет и искать после этого текст отбросив все остальное.
понятно, что на разных картинках диапазоны цветов приводящие к желаемому результату могут быть разные, поэтому желательно очень, чтобы их можно было настраивать.
как то так.
← →
Вова (2013-06-26 10:44) [9]
> например, вот такой вариант:
>
> Color:=ColorMap[Color shr 12 and $F0F or Color and $F0];
>
вау, я ничо не понял. где нибудь есть букварь по такому алгоритму?
← →
Sha © (2013-06-26 10:57) [10]Количество градаций каждой составляющей цвета уменьшаем до 16, оставляя по 4 старших бита от каждой.
Итого получаем 16*16*16 разных цветов. Будем использовать их как индекс в массиве.
Где-то в самом начале программы для инициализируем массив результирующих цветов.
Осталось вычислить индекс входного цвета в нашем массиве и извлечь оттуда результат.
← →
Sha © (2013-06-26 11:09) [11]Инициализация выглядит так:
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);
← →
Sha © (2013-06-26 11:11) [12]Нет не так, а вот так:
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);
← →
han_malign (2013-06-27 09:34) [13]
> на разных картинках диапазоны цветов приводящие к желаемому результату могут быть разные
- для уменьшения глубины цвета(квантизации) - используется обычно октантное дерево...
У Фень Юаня есть есть описание алгоритма, и здесь -
http://www.efg2.com/Lab/Graphics/Colors/ShowDemoOne.htm
← →
Sha © (2013-06-27 09:58) [14]в варианте [7,12] перенастройка выполняется аналогично инициализации,
только производится вызов другой YourSuperFunc2 или той же, но с другими параметрами
← →
Sapersky (2013-06-27 11:26) [15]пороговое преобразование работает в данном случае ненадежно, т.к. яркость фона непостоянна
http://locv.ru/wiki/5.7.1_Адаптивное_пороговое_преобразование
← →
Jeer © (2013-06-27 12:33) [16]Да, адаптивное - рулит.
Когда-то было надо, сделал свой вариант:
Константный threshold:
http://s018.radikal.ru/i503/1306/11/a134e2eddde4.jpg
Адаптивный threshold:
http://s14.radikal.ru/i187/1306/2a/8325f2f04dd5.jpg
← →
Вова (2013-06-27 14:49) [17]ща сделал как Sha написал - скорость стала как у порогового, может даж немного быстрее. if then - конкретно тормозят, даже если одно условие вставить то уже +30 милисекунд на картинку (
← →
Вова (2013-06-28 13:28) [18]эх, только вот обнаружилось, что белого при такой инициализации нет в массиве (
Во всяком случае цвет 255 255 255 получается в результате светло серым.
← →
Вова (2013-06-28 14:05) [19]Вообщем после преобразования такого 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 14:38) [20]Color shr 12 and $F0F or Color and $F0 - как это расшифровать, что это значит?)
← →
MBo © (2013-06-28 14:39) [21]>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
← →
Sha © (2013-06-28 14:47) [22]ничего этого (разбивать и понимать) не требуется
1. просто объяви таблицу для хранения вычисленных результатов
var
ColorMap: array[0..16*16*16-1] of integer;
2. заранее помести результаты вызова любой своей функции для 4k цветов в таблицу (см.[12])
3. когда требуется, вместо вызова своей функции бери результат из таблицы (см.[7])
← →
Вова (2013-06-28 14:54) [23]
> ничего этого (разбивать и понимать) не требуется1. просто
> объяви таблицу для хранения вычисленных результатовvar
> ColorMap: array[0..16*16*16-1] of integer;2. заранее помести
> результаты вызова любой своей функции для 4k цветов в таблицу
> (см.[12])3. когда требуется, вместо вызова своей функции
> бери результат из таблицы (см.[7])
я так и делал, и обнаружил что в инициализированном массиве белого цвета нет ( а если я ищу в массиве белый цвет, то он мне возвращает светлосерый.
← →
Sha © (2013-06-28 14:55) [24]не верю, код давай
← →
Sha © (2013-06-28 15:06) [25]Максимальный цвет получается при 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));
← →
Вова (2013-06-28 15:10) [26]
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:17) [27]Последнюю строчку в InitColorMap спиши из [25] - и будет тебе щастье без черного цвета.
Ты специально тормозишь программу???
Выкинь нафиг вторую функцию. Просто бери элемент массива в нужном месте программы.
А уж если когда понадобится название цвета, тогда вызывай хоть черта с рогами.
← →
MBo © (2013-06-28 15:17) [28]Я бы так скобками обложил:
(Color shr 12) and $F0F or Color and $F0
причина - приоритет and выше, чем у shr
или для читабельности (и при паранойе) вообще так:
((Color shr 12) and $F0F) or (Color and $F0)
← →
Sha © (2013-06-28 15:23) [29]> приоритет and выше, чем у shr
у меня вроде одинаковый)
← →
Sha © (2013-06-28 15:34) [30]> Вова (28.06.13 15:10) [26]
В качестве домашнего задания можешь написать инициализацию таблицы для случая ColSel<>"None".
И со сдвигами разберешься и польза для работы опять же.
← →
Sha © (2013-06-28 15:40) [31]> Вова (28.06.13 15:10) [26]
И эта. Не надо хранить имена. Правильное объявление ColorMap в [22].
← →
Вова (2013-06-28 16:04) [32]таки вы уже хотите сказать что лучше 9 массивов забубенить по 4к элементов?
← →
Вова (2013-06-28 16:05) [33]даж 10, 1 универсальный и 9 по штуке на каждый цвет.
← →
Sha © (2013-06-28 16:08) [34]Где?
Лучше 1 массив инициализировать каждый раз, когда надо.
Все твои случаи сводятся к этому.
И все будет просто летать, т.к. вызовов функции при работе с картинками вообще не будет.
← →
Вова (2013-06-28 16:12) [35]да но по сути это
1) видеопоток
2) ищутся разные объекты в разном цвете
← →
Sha © (2013-06-28 16:13) [36]Тогда 10 массивов лучше
← →
Sha © (2013-06-28 16:21) [37]искомый цвет задается не именем, а адресом массива
← →
Sha © (2013-06-28 16:24) [38]и размер элемента массива становится 1 байт (или даже бит - это можно сделать, если размер имеет значение)
← →
MBo © (2013-06-28 16:25) [39]>у меня вроде одинаковый)
:)
Это я, балбес, с прямым углом перепутал (с or, xor)
← →
Вова (2013-06-29 00:08) [40]дауш, то что вызывать сразу из массива, а не из фунции, то это если что то и дало, то я не заметил. а вот когда я убрал текст, производительность выросла в несколько раз.
Страницы: 1 2 3 4 5 6 вся ветка
Форум: "Начинающим";
Текущий архив: 2014.07.06;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.005 c