![]() |
| ||
|
|
Новости |
Поиск |
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;
Вова (2013-08-24 16:38:00) [21]не ну я на самом деле проверял, если писать в тот же битмап из которого читаешь, то он быстрее работает, т.к. хотя бы потому, что операций меньше, не нужно в целевом массиве позиционироваться на нужную ячейку. А мне плюс к тому, еще приходится переворачивать изображение, т.к. Search для перевернутого изображения я сделать не смог, у меня критично чтобы поиск начинался с самой верхней точки объекта (и во вторую очередь с самой левой).
ProgRAMmer Dimonych (2013-08-24 16:09:00) [22]> хотя кажется мне что вот этим самым копированием замедляется
> работа (
«Кажется» — это для астрологов и прочих экстрасенсов. У нас все копирования меряются и сравниваются с остальными операциями, выбирается самая медленная и оптимизируется. Процесс повторяется до получения приемлемого результата: при обработке больших массивов данных — до тех пор, пока не получится обрабатывать со скоростью, достаточной, чтобы данные не накапливались, при написании GUI-приложения — до тех пор, пока пользователь не перестанет замечать задержку во времени (кажется, около 100 мс — минимум, который можно ощутить).
Вова (2013-08-24 16:05:00) [23]короче, просто взять битмап и отрезать от него нужный байт это не варинт ) так что не пойму, чего ты разволновался то )
Вова (2013-08-24 16:00:00) [24]1) screenshot -> GrayScale -> Monochrome -> Search
2) screenshot -> Monochrome -> Search Это вариант который мы тут мучали, ничего не пропало зря. Просто мы преобразовывали битмап и в него же складывали результат, а на боевой результат копируется в массив байтов. хотя кажется мне что вот этим самым копированием замедляется работа (
Sha (2013-08-24 13:52:00) [25]> Вова (24.08.13 13:06) [184]
Просто нет слов...
И что должно получиться в итоге?
Sapersky (2013-08-24 13:16:00) [26]Раз уж ты начинаешь задумываться об альтернативах TBitmap, предложу TFastDIB, там работа с 8-битными картинками достаточно удобна:
http://sourceforge.net/projects/tfastdib/files/Library/FastDIB%204.0/FastDIB%204.0.zip/download
Чтобы получить начало в левом верхнем углу, как я уже говорил, нужно задать отрицательную высоту.
1 бит на пиксель - не нужно, неудобно обрабатывать.
Вова (2013-08-24 13:06:00) [27]на байт я уже перешел давно, правда в процессе этого топика я усомнился, что так быстрее, наблюдая за тем как быстро обрабатывается битмап.
Т.е. базовый вариант, это берется кусок скрина и переводится в градацию серого в этот момент я переношу кусок битмапа в одномерный массив of Byte, после доп обработки, я переношу во второй массив точно такой же, но в нем у меня во всех точках либо 255 либо 0, т.е. по сути уже биты....
Вот кажется мне, что быстрее прям в битмапе переводить в серый, его обрабатывать и только потом переносить в массив с байтами....или с битами?
Вова (2013-08-24 12:55:00) [28]а то что мы делали и была фильтрация и взятие скриншота, ну взятие скриншота потом переродилось в более редкое взятие скриншота в отдельном потоке и быстрое копирование его кусков в разные места )
Вова (2013-08-24 12:53:00) [29]как зачем, начинается то все со скриншота, но после обработки от него остается 1 байт на пиксель ) Хотя даже не байт, а бит ) т.е. после фильтрации все что мне нужно знать, есть в таком то месте пиксель или нет.
Sha (2013-08-24 12:25:00) [30]> все что мне нужно помещается в 1 байте на пиксель
и зачем тогда весь огород? столько времени строили...
> И еще есть ли смысл с обычным массивом работать через указатели
> ( с точки зрения быстродействия)?
небольшой дополнительный прирост можно получить,
но сначала алгоритм продумай и перейди на 1 байт, это даст гораздо больше
Вова (2013-08-24 11:56:00) [31]а вообще вопрос, целесообразно ли переходить от битмапа на одномерный массив. Особенно учитывая, что информация в битмапе явно избыточная, все что мне нужно помещается в 1 байте на пиксель, но очень важна скорость обработки. И еще есть ли смысл с обычным массивом работать через указатели( с точки зрения быстродействия)?
Вова (2013-08-24 11:37:00) [32]ощем, хз как разворачивать цикл. И акромя того, я таки стал разворачивать картинки в нормальное состояние (при переходе от бмп к массивам). Т.к. все расчитано на то, что картинка начинает обрабатывацо с левого верхнего угла, иначе если шаблон не на 100% накладываецо то всему писец. Да и полный размер программы в памяти ужо 100 мб, причем 2.8 экзешник и 97 база данных и картинки)) так что надо чо то с этим делать и битмапы нафиг слать.
Sha (2013-08-24 08:52:00) [33]Предусмотреть все невозможно.
Успех меня опять не уберег.
Ну, нафига мне в руки вложен
Судьбой тот самый молоток?
проф. Преображенский (2013-08-23 18:37:00) [34]Я вижу суть вещей отныне,
Я слышу голос неземной,
А то, что сотворю в пустыне,
Узрят пришедшие за мной.
проф. Преображенский (2013-08-23 17:04:00) [35]Я "нет" говорю вместо "да",
Сажусь туда, где недавно был стул,
Я ложку несу мимо рта,
И просыпаюсь не там где уснул.
Sapersky (2013-08-23 16:12:00) [36]Поправки к [162] и [164]:
Я забыл, что при чтении как Integer порядок байт разворачивается, т.е. в памяти BGRA, в Integer ARGB.
Шаманское преобразование для 32-х бит будет $AaRrGgBb -> $RBG. И это таки влияет на порядок индексов при просчёте таблицы:
ColorMap[r * 256 + b * 16 + g] := ...
Для RGB:
ColorMap[r * 256 + g * 16 + b] := ...
Start^ := ColorMap[(i shr 12 and $F00) or (i shr 8 and $F0) or (i shr 4 and $F)];
Sha (2013-08-23 10:40:00) [37]Таблица используется просто как кеш для запоминания результата функции.
Именно поэтому ей совершенно безразличен порядок цветов: RGB, BGR или
как еще. Альфа не кешируется.
Sha (2013-08-23 10:21:00) [38]> Sha тоже хорош - изменил порядок цветов...
Так я вроде сказал, там выше, что это некий условный номер цвета )
Если особо не вдаваться в детали и не пытаться в этом номере
увидеть нечто большее, то все будет работать, как надо.
Ведь и при записи, и при чтении данных из таблицы мы
для одинаковых цветов будем вычислять одинаковый номер.
Поэтому абсолютно без разницы где там данные лежат в таблице
Вова (2013-08-23 08:44:00) [39]мда уж, хоть с цветами все и решилось.
Но ночь плясок с бубном вокруг разворачивания изображения в разные стороны, отражения координат и т.д. и т.п. успехом не увенчались...
координата 0.0 картинки вовсе не тут Start := tBmp.ScanLine[tBmp.Height - 1];
и не тут!!! Stop := tBmp.ScanLine[0]; она вот тут: dec(Stop,tBmp.Width)
Вова (2013-08-23 03:05:00) [40]твою машу, короче мозг сломаешь
RGBV.red := color shr 16;;
RGBV.green := color shr 8;
RGBV.blue := color;
входной так, выходной как в 170, вроде цвета на место встали и я запутался окончательно )