Вверх ↑
Этот топик читают: Гость
Ответов: 202
Рейтинг: 7
#1: 2017-05-22 21:21:24 ЛС | профиль | цитата
Здравствуйте всем

Ищу желающего принять у меня заказ на компонент IC, который позволил бы мне искать в указанной области экрана изображение по образцу, который хранится в файле формата .bmp

Особенность задачи в том, что нужно сравнивать не все пикселя образца, а лишь отмеченные во втором файле с изображением-маской. Изображение-маску планируется создавать в Фотошопе, в формате, который посоветует для этой цели разработчик компонента.

Кроме того, очень нужно иметь возможность задавать допустимый уровень отклонения цвета пикселей... и допустимый процент пикселей, которые за этот уровень перевалили. По этим критериям и будет приниматься решение, найдено искомое изображение, или нет

Пли-и-из...
карма: 1

0
Ответов: 758
Рейтинг: 112
#2: 2017-05-22 21:39:07 ЛС | профиль | цитата
http://forum.hiasm.com/topic/64807 не подходит ?

Редактировалось 1 раз(а), последний 2017-05-22 21:39:59
карма: 1

0
Ответов: 202
Рейтинг: 7
#3: 2017-05-22 21:52:15 ЛС | профиль | цитата
miver писал(а):
http://forum.hiasm.com/topic/64807 не подходит ?


Если я не ошибаюсь, то там сравниваются все пиксели подряд.
У меня есть образцы инлайн-кода с нашего форума по этой теме.

Но, либо я чего-то пропустил, либо на форуме не было задания сравнивать пиксели ВЫБОРОЧНО (по маске, например), а не все подряд.

По-скольку я совсем не программер, я не в состоянии доработать имеющийся у меня инлайн-код, сравнивающий ВСЕ пиксели. Вот и ищу человека для делового сотрудничества
карма: 1

0
Ответов: 758
Рейтинг: 112
#4: 2017-05-22 22:16:22 ЛС | профиль | цитата
Выложите пример поиска и шаблон, который нужно искать.
Выберите цвет фона который не будет участвовать в сравнении (например розовый ).
Если у меня получится, то переведете деньги в донат HiAsm!

Редактировалось 1 раз(а), последний 2017-05-22 22:16:43
карма: 1

0
Ответов: 8923
Рейтинг: 823
#5: 2017-05-22 22:19:48 ЛС | профиль | цитата
miver, если в эталоне не обрабатываемые пиксели закрасить чёрным (или наоборот белым, или знаменитым фиалковым), а в коде после первого найденного пикселя c цветом +-
10% искать чёрные<>0, ваша схема вполне справится
Evgenij_Egorovich, выложите для miver-а образец экрана и образец маски на белом фоне *.bmp.

--- Добавлено в 2017-05-22 22:21:01

Раз совпало, значит в правильном направлении думаем

Редактировалось 1 раз(а), последний 2017-05-22 22:21:01
карма: 19

0
Ответов: 202
Рейтинг: 7
#6: 2017-05-22 22:23:03 ЛС | профиль | цитата
Спасибо...

Сегодня уже не успеваю, а завтра приготовлю, что и как себе представляю, и попытаюсь сюда правильно прикрепить
карма: 1

0
Ответов: 202
Рейтинг: 7
#7: 2017-05-23 12:47:58 ЛС | профиль | цитата
Добренький всем денёчек

Сюда прикрепить файлы изображения - не вижу как
Буду вставлять ссылки на свой OneDrive

Первый файл - область скриншота, в которой нужно найти изображение: https://1drv.ms/i/s!AnoSlTzMqlL6wzfPAeSMHhaYoMHV
Он 32-битный, созданный программой Lightshot

Второй файл - искомое изображение: https://1drv.ms/i/s!AnoSlTzMqlL6wzYiWv3p-crbSyN9
24-битное, создано Фотошопом

Третий - маска: https://1drv.ms/i/s!AnoSlTzMqlL6wzW1ogncfkzYR86b
8-битный, градации серого, тоже Фотошоп.
Чёрным цветом указаны пиксели, которые участвуют в сравнении, белым - которые НЕ участвуют.

-------
Теоретически, мне всё это видится где-то так...
Заказываемый компонент, через верхние точки соединён с 8-ю компонентами Memory, в которых лежат подготовленные для работы данные:
1) икс верхнего левого угла области поиска на скрине;
2) игрек верхнего левого угла области поиска на скрине;
3) икс нижнего правого угла области поиска на скрине;
4) игрек нижнего правого угла области поиска на скрине;
5) путь к файлу искомого изображения;
6) путь к файлу маски;
7) значение допустимого отклонения цвета пикселя;
8) значение допустимого процента пикселей, вылетевших за пределы допустимого отклонения цвета.

Передавать все эти данные компоненту в потоке мне как-то неуютно. Поэтому, прошу через верх

Получив управление, компонент делает скрин указанной области экрана, в которой производит поиск.
После окончания поиска, на выходе компонента мне нужны будут координаты левого верхнего угла найденного изображения, относительно нулевой точки ИЗОБРАЖЕНИЯ ОБЛАСТИ ПОИСКА. Наверно, будет удобно, если, в случае неудачи, обе координаты будут содержать просто минус единицу.

Вот, что у меня пока есть...
Естественно, я открыт для всех замечаний и предложений
карма: 1

0
Ответов: 758
Рейтинг: 112
#8: 2017-05-23 15:04:32 ЛС | профиль | цитата
1. Предлагаю искомое изображение и маску объединить

2. Если предусматривать пункты 7 и 8, то зачем маска поиска. Можно искать лучшее совпадение и при определенном проценте совпадения просто нет картинки на экране
пример - или Поиск по экрану с ограничением по ошибке. Сохранил скриншот в .jpg с 50% качеством scrnfind.rar

--- Добавлено в 2017-05-23 15:05:09

Розовый цвет в поиске участвовать не будет

Редактировалось 1 раз(а), последний 2017-05-23 15:05:09
карма: 1

0
Ответов: 202
Рейтинг: 7
#9: 2017-05-23 18:17:29 ЛС | профиль | цитата
2 miver

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

Не представляю, как можно объединить маску с изображением, если цвет пикселей в изображении имеет основное значение. Как в розовом пикселе сохранить информацию по искомому цвету - не въезжаю

(пошёл смотреть схему...)

добавлено:
Посмотрел код в компоненте. У меня точно такой, только в конце три строчечки по условию else добавлено

Редактировалось 1 раз(а), последний 2017-05-23 18:27:55
карма: 1

0
Ответов: 202
Рейтинг: 7
#10: 2017-05-23 21:08:29 ЛС | профиль | цитата
Уважаемое сообщество,

хочу уточнить, что заказываю компонент не для забавы. Он будет честно работать и зарабатывать мне реальные деньги (не подумайте про казино я в это не играюсь).
Поэтому, я собираюсь заплатить за его создание столько, сколько он реально потребует усилий от разработчика (чтоб никому обидно не было).
То есть, прошу воспринять мой заказ как серьёзное фриланс-предложение
карма: 1

0
Ответов: 817
Рейтинг: 52
#11: 2017-05-23 21:20:30 ЛС | профиль | цитата

Evgenij_Egorovich писал(а):
я собираюсь заплатить за его создание столько, сколько он реально потребует усилий от разработчика

Дарю идею для того кто возьмется за компонент.
Не назначайте конкретную сумму сразу, просите процент от будущих заработанных денег
Evgenij_Egorovich, А если не секрет, что это будет в результате?
Я не могу придумать ничего кроме как "рисовать мультики"

Редактировалось 1 раз(а), последний 2017-05-23 21:22:25
карма: 1

0
Ответов: 16884
Рейтинг: 1239
#12: 2017-05-23 21:45:28 ЛС | профиль | цитата
-= DriveR =- писал(а):
что это будет в результате?
Поиск преступников в БД МВД
карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
Ответов: 202
Рейтинг: 7
#13: 2017-05-23 21:50:01 ЛС | профиль | цитата
-= DriveR =- писал(а):

Evgenij_Egorovich, А если не секрет, что это будет в результате?
Я не могу придумать ничего кроме как "рисовать мультики"


Это автоматизация моей ручной торговли на Форексе... и интересные задумки помощи супруге в её работе сметчиком.
Встроенный в торговый терминал язык MQL для написания "советников" я использовать серьёзно опасаюсь, ибо неоднократно был свидетелем "странного" отказа работать у "советника" в самый ответственный момент.

Готовые автокликеры меня не устраивают отсутствием технологии графического программирования скриптов... и невозможностью мне самому изменять код непосредственно автокликера.

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

Вот...
карма: 1

0
Ответов: 758
Рейтинг: 112
#14: 2017-05-23 21:57:45 ЛС | профиль | цитата
Вот пример без маски

Add(ScreenShort,10756950,322,168)
{
link(onCapture,16345822:doCopy,[])
}
Add(Img_Copy,16345822,364,168)
{
@Hint=#17:Обрезка скриншота|
X=50
Y=50
Width=100
Height=100
Point(Result)
Point(Width)
Point(Height)
AddHint(-40,47,117,13,@Hint)
}
Add(MainForm,10552383,581,259)
{
Width=563
Height=433
Position=1
Point(onChar)
Point(doPicture)
}
Add(Image,3103349,329,259)
{
Width=160
Height=155
AutoSize=0
ViewStyle=4
Picture=[ZIPE658000078DAED9C3F6853411CC75F717775702916C4415711040B0DC221B869E9A8DD830E3738485D9C040533BFC5C5C54530E0F81691D0B169110A253625A5FFD2A48A88B4F5E7FD2EF93D5F2EF79286264DD37EBF8F23F7EEDF7BBFCFFDEE77475A32757F7D26B0BA69D23593A64D9A32692C18B7E51F4DFD978B8D242208822008822008822008822008822008822008822068202A140A480348755C47BAC06A34B8560FAAB4F567CB7E826BFF9896EB655ADE58A6B5BDB573CDB65F5CD77E6C58A6C1C41CCD7F9BA785D202ADECAC9E5BB6FDE0BAB35FB5FEC94C835B5FED6761B160D996EBDDFD361BD589FFF54B5231CCD8F23C7179362ECF98542FE5E2BA8CA9937BF72A725F958BFBE654D02C6D1F37AF83AECF3B69AECC2C667AE7375D7D4C144C6EB6B0FD5E2BA7B2CD8445CAF2FB5BAB5A79B9EC7225BECF78EBDC2BD0F916967C2FFC72661EA59FF0E7B974C714CEF5287BA25C770EAB54F959B10CAF4C13CDBE229A794934FEC8B0BD5D8CD92EAE2EDA76B5BFB596FE3E369DB80A03B6B313576E97E176893A9E932CCF4973FEDCB965E6BE313BF51B1457F64166F7E603C5E9DE0BA2CBCCF5EE3A0537DEDBFAA5F292771FF3BD732FFE9A5CB3693EDF690E65CC80C74C992BDF1C0D9AEBB3B79F1BEBBF999EBF23BAFE94E8C2436A29D7AF3FD9B397EBAF6C534E65E2B5CA7E938C6BBDB0E3BEB2EE8FC235197F659DA7719535328CF380F8EDC413A2B1070DAE76DFDAABA4F6E9B6C65C3B797F4BEE316E2C4CF3735F3DCF97EC8F9D7CFAB4709D9C23BA34DBE0BAB2BD42EBBF3653FB747BE75ED8F5C295E727B9A775E23A8CF8CAD7F6FEAE3726C8DAAF1EEC76EC9F8C99F1B94BE7AD1DBEF82A361E270EB8ACF8BE1EE552CF03B24686C1F53897EC1DEE59D38DAF6E2CECE56CEB8B296EDCF63DCF8D1527C575F7B0866F59F07D16B8822BAE3E70C5DF4C0693A0A3AB52A90002B8822BB80202B8822BB802C229E61A96888240C5DF05858A7F5EA3441171B9A652A86C3BBE57E6DE14B4E5B91D45DA5B2EE3463AF03E53F1CF7998F6256EAFC2F8F9EE334789AB8EC8DAC64C923653F49F8BD89DC655990EA1611F699DDA4698097B9907799E0E5493A2A9332FE59BCB51E19AB4D527B12964C65A7999954C5EF318A644191E11734EE1AAB89DC9BB1C85A5BC0767936B66D4B8FAECF371659BD8EE28D26DCC7418C6EBDBF2307E961607D2FCD3E5CAA59AC730B951E51A2A15C7B24E5C6D5E3157D5C2552915DB6C7D52876D6D249F64E5C601E9138FD3F4EDB3EEAF2C8EA3C958CB6C927B4C5A1B773FF4ED95C95824F149EA64BCB3125F71CE3AFE19CB771E0057EA8BDFFAD62BB842E00AAEE00A812BB8822B340CAEFF00557C49CC]
}
Add(Button,3884042,210,322)
{
Left=170
Top=5
link(onClick,8282293:doStart,[])
}
Add(Image,5758247,462,245)
{
Left=120
Top=120
Width=40
Height=40
AutoSize=0
ViewStyle=4
Picture=[ZIP5E05000078DACD54B111C2300C34050D053523A4A06600DCA46105367097495C670CF72918210364056F109E3CD1E964438E8E9C75E79365E9F57AE77ABBEFDDF25D600DEC0C3BC076EEB4F81B9C3F8EB4F5CB73FE9315862CA8C6DEC3936678023D1E50A748A777817BBD4604B791C1B1455FA3C9903AF7292797EFC7F02224E92ABA5C9CB0F7C6A997EB9294C69E15E390194984684D5F279E3C84B2B52A0626417C15034E3D4E57270007005E3AD26D0298B92E91E6CA260F4266499DC92000701DDC972D087804C4D69346A095496D964330F9FF82417452E55CE8AD5267E2A15811951E68C998F1033E155EA54830C8E60B866AB94D0C402E42AD62D0EDCBB8DFEFB48333193D30F8A75998127988E5BB20BD5A36FA816B3DE8816EFE34CC10B5A24C4E19D313DDC38EAD]
Point(doTop)
Point(doLeft)
Point(onMouseDown)
Point(Handle)
Point(onMove)
Point(Left)
Point(Top)
link(onMouseDown,16176673:doMove,[(501,258)(501,328)])
link(onMove,12620521:doString,[])
}
Add(InlineCode,2366711,329,322)
{
WorkPoints=#12:doFindBitmap|
EventPoints=#8:onResult|8:SumError|
DataPoints=#6:Bitmap|9:subBitmap|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|29:uses Windows,kol,Share,Debug;|0:|4:type|40: TByteArray = array [0..32767] of Byte;|27: PByteArray = ^TByteArray;|35: TBuf = array of array of integer;|15: FRes = record|19: found: boolean;|17: x,y: integer;|17: percent:real;|6: end;|14: WH2 = record|43: Width1,Height1,Width2,Height2: integer;|6: end;|2: |28: THiAsmClass = class(TDebug)|10: private|0:|9: public|12: Bitmap,|15: subBitmap,|35: onResult, SumError: THI_Event;|57: procedure doFindBitmap(var _Data:TData; Index:word);|65: function CompareIMG(var buf1:TBuf; buf2:TBuf; WH:WH2): FRes;|5: end;|0:|14:implementation|0:|40:function LoagIMG(var Bmp:PBitmap) :TBuf;|3:var|17: x,y,c: integer;|16: p: pByteArray;|15: buffer: TBuf;|5:begin|36: Bmp.PixelFormat:=pf24Bit;//pf8Bit;|43: SetLength(buffer, Bmp.Height, Bmp.Width);|35: for y:=0 to Bmp.Height-1 do begin|23: p:=Bmp.ScanLine[y];|36: for x:=0 to Bmp.Width-1 do begin|52: c:=((p[x*3+0] shl 8+p[x*3+1]) shl 8)+p[x*3+2];|21: buffer[y,x]:=c;|8: end;|6: end;|19: Result := buffer;|4:end;|0:|72:function THiAsmClass.CompareIMG(var buf1:TBuf; buf2:TBuf; WH:WH2): FRes;|3:var|29: y, x, yy, xx, err: integer;|23: sumerr, sum: LongInt;|5:begin|58: //maxerr:=200; //максимальная ошибка = в диапазоне 0-726|21: sum:=High(LongInt);|22: Result.found:=false;|7: y:=0;|8: repeat|9: x:=0;|10: repeat|25: Result.found:=true;|16: sumerr:=0;|12: yy:=0;|12: repeat|14: xx:=0;|14: repeat|55: //Result.found:=buf1[y+yy, x+xx]=buf2[yy,xx];|71: err:=abs(byte(buf1[y+yy, x+xx]) - (buf2[yy,xx] and $0000ff))+|91: abs((buf1[y+yy, x+xx] and $00ff00 shr 8) - (buf2[yy,xx] and $00ff00 shr 8))+|93: abs((buf1[y+yy, x+xx] and $ff0000 shr 16) - (buf2[yy,xx] and $ff0000 shr 16));|51: //if err>maxerr then Result.found:=false;|29: sumerr:=sumerr+err;|49: if sumerr>sum then Result.found:=false;|18: inc(xx);|52: until (xx>=WH.Width2) or (Not Result.found);|16: inc(yy);|51: until (yy>=WH.Height2) or (Not Result.found);|30: if sumerr<sum then begin|21: sum:=sumerr;|21: Result.x:=x;|21: Result.y:=y;|59: Result.percent:=sumerr/(726*WH.Width2*WH.Height2);|10: end;|13: inc(x);|34: until (x>WH.Width1-WH.Width2);|11: inc(y);|34: until (y>WH.Height1-WH.Height2);|21: Result.found:=true;|30: //if Result.found then begin|20: //Result.x:=x-1;|20: //Result.y:=y-1;|8: //end;|4:end;|0:|35:procedure THiAsmClass.doFindBitmap;|3:var|24: Bmp, subbmp:PBitmap;|21: FindResult: FRes;|21: buf1, buf2: TBuf;|12: WH: WH2;|16: dt,di:TData;|5:begin|36: Bmp := ReadBitmap(_Data,Bitmap);|42: if (Bmp = nil) or Bmp.Empty then exit;|42: subbmp := ReadBitmap(_Data,subBitmap);|48: if (subbmp = nil) or subbmp.Empty then exit;|73: if (Bmp.Width<subbmp.Width) or (Bmp.Height<subbmp.Height) then exit;|4: |25: buf1 := LoagIMG(Bmp);|25: WH.Width1:=Bmp.Width;|27: WH.Height1:=Bmp.Height;|15: //Bmp.Free;|4: |28: buf2 := LoagIMG(subbmp);|28: WH.Width2:=subbmp.Width;|30: WH.Height2:=subbmp.Height;|22: //subbmp.Free; |4: |43: FindResult:=CompareIMG(buf1, buf2, WH);|4: |15: dtNull(dt);|15: dtNull(di);|34: if FindResult.found then begin|57: dtInteger(dt,FindResult.x);//+(WH.width2 div 2));|58: dtInteger(di,FindResult.y);//+(WH.height2 div 2));|24: dt.ldata := @di;|34: _hi_onEvent(onResult, dt);|50: _hi_onEvent(SumError, FindResult.percent);|8: end;|4:end;|4:end.|
link(onResult,13902867:doEvent1,[])
link(SumError,4467059:doCalc,[(375,335)(375,370)])
link(Bitmap,3103349:ImageBitmap,[])
link(subBitmap,5758247:ImageBitmap,[(342,313)(468,313)])
}
Add(MT_Part,15868768,420,259)
{
link(onSplit,5758247:doTop,[])
link(onPart,5758247:doLeft,[])
}
Add(MoveWindow,16176673,525,322)
{
link(Handle,5758247:Handle,[(531,313)(475,313)])
}
Add(Label,7469250,567,364)
{
Left=230
Top=10
Width=115
}
Add(FormatStr,8296708,525,364)
{
DataCount=1
Mask="Минимальная ошибка - %1 %"
link(onFString,7469250:doText,[])
}
Add(Hub,13902867,385,322)
{
link(onEvent1,8282293:doStop,[(417,328)(417,377)(270,377)(270,335)])
link(onEvent2,15868768:doSplit,[(410,335)(410,265)])
}
Add(TimeCounter,8282293,280,322)
{
link(onStart,2366711:doFindBitmap,[])
link(onStop,6823186:doString,[(319,335)(319,398)])
}
Add(Label,15385577,385,392)
{
Left=230
Top=35
}
Add(FormatStr,6823186,336,392)
{
DataCount=1
Mask="Время поиска - %1 Millisecond"
link(onFString,15385577:doText,[])
}
Add(MathParse,4467059,476,364)
{
DataCount=1
MathStr="round(%1*100,0.01)"
link(onResult,8296708:doString,[])
}
Add(FormatStr,12620521,525,259)
{
Mask="x = %1, y = %2"
link(onFString,10552383:doCaption,[])
link(Str1,6079462:Wire1,[])
link(Str2,6079462:Wire2,[])
}
Add(CableData,1772919,476,287)
{
link(Wire1,5758247:Left,[])
link(Wire2,5758247:Top,[])
}
Add(CableVar,6079462,525,231)
{
link(Cable,1772919:Cable,[(531,222)(517,222)(517,306)(482,306)])
}
карма: 1

0
Ответов: 202
Рейтинг: 7
#15: 2017-05-23 22:12:35 ЛС | профиль | цитата
miver писал(а):
Вот пример без маски


Маска мне очень нужна . У меня на неё большие планы.
Наличие маски сулит мне значительные выгоды. Плюс возможность отфильтровывать результаты сравнения ненужных мне пикселей.

А схема, работающая без маски у меня есть
карма: 1

0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)