Здравствуйте, гость ( Вход | Регистрация )

> Разработка findcolor, findimage, Pure lua
DarkMaster
сообщение 24.3.2021, 18:01
Сообщение #1


***********

Модератор UOPilot
Сообщений: 9.735
Регистрация: 2.12.2008
Группа: Супермодераторы
Наличность: 29622
Пользователь №: 11.279



Собственно обсуждение багов, фич, функционала, тесты и прочее.

Сообщение отредактировал DarkMaster - 27.3.2021, 13:38


--------------------
Скрипты UOPilot под заказ.
Консультации по UOpilot 15$/час.
Услуги Lua разработчика (не пилот, проекты, постоянка)
Disсоrd:
Kov____
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
 
Ответить в эту темуОткрыть новую тему
Ответов
DarkMaster
сообщение 30.3.2021, 18:54
Сообщение #2


***********

Модератор UOPilot
Сообщений: 9.735
Регистрация: 2.12.2008
Группа: Супермодераторы
Наличность: 29622
Пользователь №: 11.279



поправлен парсиг color_deviation_*
Код
--lua

local ffi=require "ffi"
local rmem=ffi.cast
local C=ffi.C

local SRCCOPY = 0x00CC0020
local DIB_RGB_COLORS = 0
local BI_RGB = 0
ffi.cdef[[
    typedef long LONG;
    typedef unsigned short WORD;
    typedef unsigned long DWORD;
    typedef unsigned char BYTE;
    typedef void *LPVOID;
    typedef struct {DWORD biSize; LONG  biWidth; LONG  biHeight; WORD  biPlanes; WORD  biBitCount; DWORD biCompression; DWORD biSizeImage;
        LONG  biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant;} BITMAPINFOHEADER;
    typedef struct {BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved;} RGBQUAD;
    typedef struct {BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1];} BITMAPINFO;
    int GetDC(int hWnd);
    int ReleaseDC(int hWnd, int hDC);
    int SelectObject(int hdc, int h);
    int CreateCompatibleDC(int hdc);
    int CreateCompatibleBitmap(int hdc, int cx, int cy);
    bool DeleteObject(int ho);
    bool BitBlt(int hdc, int x, int y, int cx, int cy, int hdcSrc, int x1, int y1, unsigned long rop);
    int GetDIBits(int hdc, int hbm, unsigned int start, unsigned int cLines, LPVOID lpvBits, BITMAPINFO* lpbmi, unsigned int usage);

    void free(void *ptr);
    void *malloc(size_t size);
]]

local ext = {}
local internal = {}
local images = {}

ext.wait           = {} -- блок дейстивий по ожиданию цвета/изображений/кликов/окон.
ext.wait.log       = 1  -- включить ввывод description в лог.
ext.wait.log_level = 2  -- уровень логирования для description.
ext.lg_level  = 1       -- уровень логирования. Для вывода сообщения должен быть больше или равен
                        -- заданному при вызове функции.
                        -- Если при вызове функции уровень не задан, то он считается равным 0.

function ext.lg(data, comment, level)
    if  (not level and ext.lg_level < 0) or (level and level < ext.lg_level) then
        return
    end
    if  comment ~= nil then
        log(comment)
    end

    local tab = ""
    local deep = 0

    local function show(data)
        -- Пишем в лог комментарий.
        deep = deep + 1 -- Уровень вложенности вызовов функции.

        if type(data) == "table"    then
            local element_counter = 0
            for k,v in pairs(data) do
                element_counter = element_counter + 1
                if  type (v) == "table" then
                    log(tab..'table: '..tostring(k))
                    tab = tab .. "    "
                    show(v)
                    tab = string.sub(tab, 1, -5)
                else
                    if     type(v) == "nil"       then v = "nil"
                    elseif type(v) == "string"    then v = '"' .. v .. '"'
                    elseif type(v) == "number"    then v = tostring(v)
                    elseif type(v) == "function"  then v = tostring(v)
                    elseif type(v) == "thread"    then v = tostring(v)
                    elseif type(v) == "userdata"  then v = "userdata"
                    elseif type(v) == "boolean"   then v = tostring(v)
                    elseif type(v) == "table"     then
                        log(tab..""..k.." = "..v or "nil")
                    else
                        v = "uknown data type"
                    end
                    log(tab..""..k.." = " .. v)
                end
            end
            log(tab.."".."Elements in table: " .. element_counter)
        else
            log('table is "' .. type(data) .. '" data type. Value: ' .. tostring(data))
        end
        
        --tab = ""
        --deep = 0
    end
    
    show(data)
end


ext.getimage = function(x1, y1, x2, y2, handle, abs_flag)
    if handle > 2 or handle == 0 then
        local a, w, h, l
        w = x2-x1 + 1
        h = y2-y1 + 1
        
        local hdcWindow = C.GetDC(handle or 0)  -- если хендл не указан, то получим скрин с экрана
        local hdcMemDC = C.CreateCompatibleDC(hdcWindow)
        local hbmScreen = C.CreateCompatibleBitmap(hdcWindow, w, h)
        
        C.SelectObject(hdcMemDC,hbmScreen)
        C.BitBlt(hdcMemDC, 0, 0, w, h, hdcWindow, x1, y1, SRCCOPY)  -- сохранить в памяти скрин с окна или экрана

        local bi = ffi.new('BITMAPINFO', { {ffi.sizeof('BITMAPINFOHEADER'), w, -h, 1, 24, BI_RGB,0,0,0,0,0} })
        C.GetDIBits(hdcWindow, hbmScreen, 0, h, nil, bi, DIB_RGB_COLORS)   -- узнать какого размера нужен массив

        local bitmap_address = ffi.gc(C.malloc(bi.bmiHeader.biSizeImage), C.free)
        local h_copied = C.GetDIBits(hdcWindow, hbmScreen, 0, h, bitmap_address, bi, DIB_RGB_COLORS)   -- получить битовый массив


        --return h_copied and ffi.cast("int", bitmap_address) or nil, w, h_copied, math.floor(w*3/4+0.75)*4
        if h_copied > 0 then
            a = tonumber(ffi.cast("int", bitmap_address))
            
            images[a] = {}
            images[a].handle = handle
            images[a].hdcWindow = hdcWindow
            images[a].hdcMemDC = hdcMemDC
            images[a].hbmScreen = hbmScreen
            images[a].bitmap_address = bitmap_address

            return a, w, h_copied, math.floor(w*3/4+0.75)*4
        else
            return nil
        end
    else
        return internal.getimage_orig(x1, y1, x2, y2, handle, abs_flag)
    end
end

internal.deleteimage_orig = deleteimage
ext.deleteimage = function(address)
    if images[address] then
        C.ReleaseDC(images[address].handle, images[address].hdcWindow)            
        C.DeleteObject(images[address].hdcMemDC)
        C.DeleteObject(images[address].hbmScreen)
        ffi.C.free(ffi.gc(images[address].bitmap_address, nil)) -- Manually free the memory
        images[address] = nil
    else
        deleteimage_orig(address)
    end
end

-- Раскладывает код цвета на отдельные каналы.
ext.color_to_rgb = function(c)
    local r,g,b
    b = math.floor(c/65536)
    g = math.floor(c/256-b*256)
    r = c-b*256*256-g*256
    return r, g ,b
end

ext.color_to_bgr = function(c)
    local r,g,b
    b = math.floor(c/65536)
    g = math.floor(c/256-b*256)
    r = c-b*256*256-g*256
    return b, g, r
end

ext.rgb_to_color = function(r, g, b)
    return b*256*256 + g*256 + r
end

ext.bgr_to_color = function(b, g, r)
    return b*256*256 + g*256 + r
end

--   ВНИМАНИЕ ФИКС СТАНДАРТНОЙ ФУНКИИ
--   ОРИГИНАЛЬНАЯ ФУНКЦИЯ ПОЛНОСТЬЮ ЗАМЕНЕНА
colortorgb = ext.color_to_rgb

internal.color_deviation_parse = function(b1, g1, r1, b2, g2, r2)
    if type(b1) == "table" then
    
    else
    
    end

    if not g1 then
        g1 = b1
        r1 = b1
        b2 = b1
        g2 = b1
        r2 = b1
    elseif not b2 then
        b2 = b1
        g2 = g1
        r2 = r1
    else
        -- Ставим минимальные значения вначале, максимальные вконце.
        b1, g1, r1, b2, g2, r2 = b2, g2, r2, b1, g1, r1
    end
    return b1, g1, r1, b2, g2, r2
end

--[[==
internal.color_deviation_parse = function(c1, c2, b1, g1, r1, b2, g2, r2)
    if type(b1) == "table" then
        if type(g1) == "table" then
            b2 = g1[1]
            g2 = g1[2]
            r2 = g1[3]
        else
            r2 = b2
            g2 = r1
            b2 = g1
        end
        r1 = b1[3]
        g1 = b1[2]
        b1 = b1[1]
    elseif type(b2) == "table" then
        r2 = b2[3]
        g2 = b2[2]
        b2 = b2[1]
    elseif not g1 and not r1 and not b2 and not g2 and not r2 then
        g1 = b1
        r1 = b1
        b2 = b1
        g2 = b1
        r2 = b1
    end

    if not b2 and not g2 and not r2 then
        r2 = r1
        g2 = g1
        b2 = b1
    end
    
    local c1r, c1g, c1b
    c1b = math.floor(c1/65536)
    c1g = math.floor(c1/256-c1b*256)
    c1r = c1-c1b*256*256-c1g*256
    
    local c2r, c2g, c2b
    c2b = math.floor(c2/65536)
    c2g = math.floor(c2/256-c2b*256)
    c2r = c2-c2b*256*256-c2g*256
    
    
    return b1, g1, r1, b2, g2, r2, c1r, c1g, c1b, c2r, c2g, c2b
end
]]

internal.color_deviation_a = function(c1b1, c1g1, c1r1, c1b2, c1g2, c1r2, c2b, c2g, c2r, b1, g1, r1, b2, g2, r2)
    if  c1r1 - b1 <= c2r and c1g1 - g1 <= c2g and c1b1 - r1 <= c2b and
        c1r2 + b2 >= c2r and c1g2 + g2 >= c2g and c1b2 + r2 >= c2b then
        return true
    else
        return false
    end
end

internal.color_deviation_r = function(c1b1, c1g1, c1r1, c1b2, c1g2, c1r2, c2b, c2g, c2r, b1, g1, r1, b2, g2, r2)
    local r1d = math.ceil(c1r1 * r1 * 0.01)
    local g1d = math.ceil(c1g1 * g1 * 0.01)
    local b1d = math.ceil(c1b1 * b1 * 0.01)
    
    local r2d = math.ceil(c1r2 * r2 * 0.01)
    local g2d = math.ceil(c1g2 * g2 * 0.01)
    local b2d = math.ceil(c1b2 * b2 * 0.01)

    if  c1r1 - r1d <= c2r and c1g1 - g1d <= c2g and c1b1 - b1d <= c2b and
        c1r2 + r2d >= c2r and c1g2 + g2d >= c2g and c1b2 + b2d >= c2b then
        return true
    else
        return false
    end
end

internal.color_deviation_s = function(c1b1, c1g1, c1r1, c1b2, c1g2, c1r2, c2b, c2g, c2r, br1, rg1, gb1, br2, rg2, gb2)
    c1b1, c1g1, c1r1, c1b2, c1g2, c1r2, c2b, c2g, c2r = c1b1+1, c1g1+1, c1r1+1, c1b2+1, c1g2+1, c1r2+1, c2b+1, c2g+1, c2r+1

    local c1br1 = c1b1/c1r1
    local c1rg1 = c1r1/c1g1
    local c1gb1 = c1g1/c1b1
    
    local c1br2 = c1b2/c1r2
    local c1rg2 = c1r2/c1g2
    local c1gb2 = c1g2/c1b2    
    
    local br_d1 = c1br1 * br1 * 0.01
    local rg_d1 = c1rg1 * rg1 * 0.01
    local gb_d1 = c1gb1 * gb1 * 0.01
    
    local br_d2 = c1br2 * br2 * 0.01
    local rg_d2 = c1rg2 * rg2 * 0.01
    local gb_d2 = c1gb2 * gb2 * 0.01
    
    local c2br = c2b/c2r
    local c2rg = c2r/c2g
    local c2gb = c2g/c2b
    
    --[[
    log(
    "", c1b1, c1g1, c1r1, "\r\n",
        c1b2, c1g2, c1r2, "\r\n",
        c2b, c2g, c2r
    )
    
    log(
    "", c1br1, c1rg1, c1gb1, "\r\n",
        c1br2, c1rg2, c1gb2, "\r\n",
        c2br,  c2rg,  c2gb
    )
    
    log(
    "", c1br1 , br_d1 , c2br , c1rg1 , rg_d1 , c2rg , c1gb1 , gb_d1 , c2gb , "\r\n",
        c1br2 , br_d2 , c2br , c1rg2 , rg_d2 , c2rg , c1gb2 , gb_d2 , c2gb
    )
    log(
    "", tostring(c1br1 - br_d1 <= c2br) , tostring(c1rg1 - rg_d1 <= c2rg) , tostring(c1gb1 - gb_d1 <= c2gb) , "\r\n",
        tostring(c1br2 + br_d2 >= c2br) , tostring(c1rg2 + rg_d2 >= c2rg) , tostring(c1gb2 + gb_d2 >= c2gb)
    )
    
    log(
    "", c1br1 - br_d1 ,"<=", c2br , c1rg1 - rg_d1 ,"<=", c2rg , c1gb1 - gb_d1 ,"<=", c2gb , "\r\n",
        c1br2 + br_d2 ,">=", c2br , c1rg2 + rg_d2 ,">=", c2rg , c1gb2 + gb_d2 ,">=", c2gb
    
    )
    ]]

    if  c1br1 - br_d1 <= c2br and c1rg1 - rg_d1 <= c2rg and c1gb1 - gb_d1 <= c2gb and
        c1br2 + br_d2 >= c2br and c1rg2 + rg_d2 >= c2rg and c1gb2 + gb_d2 >= c2gb then
        return true
    else
        return false
    end
end

internal.color_deviation = function(compare_func, c1, c2, b1, g1, r1, b2, g2, r2)
    local b1, g1, r1, b2, g2, r2 = internal.color_deviation_parse(b1, g1, r1, b2, g2, r2)
    local c2b, c2g, c2r = ext.color_to_bgr(c2)
    local cc = internal.parse_split_color_to_min_max_bgr(c1)

    return compare_func(cc[1][0], cc[1][1], cc[1][2], cc[1][3], cc[1][4], cc[1][5], c2b, c2g, c2r, b1, g1, r1, b2, g2, r2)
end

--[==[ color_deviation_a
-- Возвращает true, если результат
-- входит в допустимое отклонение цвета,
-- иначе вернет false.
-- Все цвета задаются в формате bgr, не rgb.
-- Пилот так же предоставляет цвета в формате bgr.
-- b, g, r в любом варианте могут быть заданы таблицей.
-- Допустимый синтаксис:
-- <цвет1>, <цвет2>, <value>
-- Значения допустимого отклонения
-- ситаются допустимыми +/- b, g, r.
-- <цвет1>, <цвет2>, <b, g, r>
-- Значения допустимого отклонения
-- ситаются допустимыми +/- b, g, r.
-- <цвет>, <цвет2>, <b1, g1, r1>, <b2[, g2[, r2]]>
-- Значения b1, g1, r1 считаются допустимыми в плюс.
-- Значения b2, g2, r2 считаются допустимыми в минус.
-- Минус не пишется.]==]

ext.color_deviation_a = function(c1, c2, b1, g1, r1, b2, g2, r2)  
    return internal.color_deviation(internal.color_deviation_a, c1, c2, b1, g1, r1, b2, g2, r2)
end

--[==[ color_deviation_r
-- Возвращает true, если результат
-- входит в допустимое отклонение цвета,
-- иначе вернет false.
-- Все цвета задаются в формате bgr, не rgb.
-- Пилот так же предоставляет цвета в формате bgr.
-- b, g, r в любом варианте могут быть заданы таблицей.
-- Погрешность задется в
-- ПРОЦЕНТАХ от текущего значения канала,
-- с округлением в бОльшую сторону.
-- Например при цвете точки: 50 101 200 и погрешности
-- равной 10% допустимая погрешность составит:
-- 50*10%=5, 101*10%=10.1=11, 200*10%=20
-- 50 101 200 исходный цвет
-- 45  90 180 минимально допустимый
-- 55 112 220 максимально допустимый
-- Допустимый синтаксис:
-- <цвет1>, <цвет2>, <value>
-- Значения допустимого отклонения
-- ситаются допустимыми +/- b, g, r.
-- <цвет1>, <цвет2>, <b, g, r>
-- Значения допустимого отклонения
-- ситаются допустимыми +/- b, g, r.
-- <цвет>, <цвет2>, <b1, g1, r1>, <b2[, g2[, r2]]>
-- Значения b1, g1, r1 считаются допустимыми в плюс.
-- Значения b2, g2, r2 считаются допустимыми в минус.
-- Минус не пишется.]==]

ext.color_deviation_r = function(c1, c2, b1, g1, r1, b2, g2, r2)  
    return internal.color_deviation(internal.color_deviation_r, c1, c2, b1, g1, r1, b2, g2, r2)
end

--[==[ color_deviation_s
-- Возвращает true, если результат
-- входит в допустимое отклонение цвета,
-- иначе вернет false.
-- Все цвета задаются в формате bgr, не rgb.
-- Пилот так же предоставляет цвета в формате bgr.
-- b, g, r в любом варианте могут быть заданы таблицей.
-- Погрешность задется в
-- ПРОЦЕНТАХ от ОТНОШЕНИЯ каналов друг к другу,
-- с округлением в бОльшую сторону.
-- Например при цвете точки: 50 101 200 и погрешности
-- равной 10% допустимая погрешность составит:
-- 50*10%=5, 101*10%=10.1=11, 200*10%=20
-- 50 101 200 исходный цвет
-- 45  90 180 минимально допустимый
-- 55 112 220 максимально допустимый
-- Допустимый синтаксис:
-- <цвет1>, <цвет2>, <value>
-- Значения допустимого отклонения
-- ситаются допустимыми +/- br, rg, gb.
-- <цвет1>, <цвет2>, <br, rg, gb>
-- Значения допустимого отклонения
-- ситаются допустимыми +/- br, rg, gb.
-- <цвет>, <цвет2>, <br1, rg1, gb1>, <br2[, rg2[, gb2]]>
-- Значения br1, rg1, gb1 считаются допустимыми в плюс.
-- Значения br2, rg2, gb2 считаются допустимыми в минус.
-- Минус не пишется.]==]

ext.color_deviation_s = function(c1, c2, br1, rg1, gb1, br2, rg2, bg2)  
    return internal.color_deviation(internal.color_deviation_s, c1, c2, br1, rg1, gb1, br2, rg2, bg2)
end

internal.parse_channel_to_min_max = function(v)
        local min, max
        if v then
            min, max = string.match (v, "([0-9x]+)-*([0-9x]*)")
            min = tonumber(min)
            max = tonumber(max)
            if not max then max = min end              
        else
            min, max = 0, 255
        end
        return min, max
    end

internal.parse_split_color_to_min_max_bgr = function(c)
    c = type(c) == "table" and c or {c}
    if c.r or c.g or c.b then
        c = {c}
    end
    local cc = ffi.new("uint8_t["..#c.."][6]")
    --log(type(c,#c))
    for i = 1, #c do
        if type(c[i]) == "table" then
            cc[i][0],cc[i][3] = internal.parse_channel_to_min_max(c[i].b)
            cc[i][1],cc[i][4] = internal.parse_channel_to_min_max(c[i].g)
            cc[i][2],cc[i][5] = internal.parse_channel_to_min_max(c[i].r)
        else
            local c1, c2 = string.match (c[i], "([0-9x]+)-*([0-9x]*)")
            c1 = tonumber(c1)
            c2 = tonumber(c2)
            cc[i][0] = math.floor(c1/65536)
            cc[i][1] = math.floor(c1/256-cc[i][0]*256)
            cc[i][2] = c1-cc[i][0]*256*256-cc[i][1]*256
            if c2 then
                cc[i][3] = math.floor(c2/65536)
                cc[i][4] = math.floor(c2/256-cc[i][3]*256)
                cc[i][5] = c2-cc[i][3]*256*256-cc[i][4]*256
            else
                cc[i][3],cc[i][4],cc[i][5] = cc[i][0],cc[i][1],cc[i][2]
            end
        end
    end

    return cc
end

internal.findcolor_deviation_parse = function(v)
    if type(v) == "number" then
        if v > 0 then
            v = {v, v, v, v, v, v}
        else
            v = nil -- вырубаем обработку отклонений.
        end
    elseif type(v) == "table" then
        vv[i][0],vv[i][3] = internal.parse_channel_to_min_max(c[i].b)
        vv[i][1],vv[i][4] = internal.parse_channel_to_min_max(c[i].g)
        vv[i][2],vv[i][5] = internal.parse_channel_to_min_max(c[i].r)
    end
    return v[1], v[2], v[3], v[4], v[5], v[6]
end

--[====[ findcolor
-- Функция поиска цвета либо нескольких цветов,
-- с возможностью задать некоторые отклонения в оттенке.
-- Синтаксис:
-- result = findcolor(<x_start, y_start, x_end, y_end | table_crds>,
-- <color> [,method [,count [,deviaton [,deviation_type [,abs_flag]]]])
--
-- <x_start, y_start, x_end, y_end | table_crds>
-- Координтаы задаются в виде прямоугольной области
-- с указанием координаты левого верхнего угла
-- и правого нижнего угла.
-- Координаты могут быть заданы четырмя переменными:
-- x_start, y_start, x_end, y_end
-- либо массивом с аналогичной структурой данных:
-- {x_start, y_start, x_end, y_end}
-- Отсчет координат начинатся с 0, а не 1.
-- Т.е. для FullHD область поиска будет
-- 0, 0, 1919, 1079.
--
-- <color>
-- Цвета, которые непосредственно ищются.
-- Синтаксис списка цветов:
-- <color | {color_1 [,color_2 [,... [,color_N]]]}>
-- Допустимые форматы цвета:
-- < dec_hex_color | dec_hex_color_1-dec_hex_color_2 |
-- {[r=val_1] [,g=val_2] [,b=val_3]} | [{r="val_1-val_2"] [,g="val_3-val_4"] [,b="val_5-val_6"}] >
-- Форматы цветов можно кобинировать в рамках списка. Например:
-- 133972, 0x5060DD-0x5170DD, {r=10, g=0xFF, b=12-18}
--
-- [method]
-- Метод поиска. Значение по умолчанию: 2
-- 0/не задан     - Быстрый метод. Получить изображение всего экрана.
-- 1              - устаревший метод, используется для совместимости. Очень медленный.
--                  Для получения изображения всего экрана, а не окна используйте abs_flag.
-- 2              - надежный метод. Средняя скорость.
--                  Для получения изображения всего экрана, а не окна используйте abs_flag.
-- хендла_окна    - очень быстрый метод. Работает с перекрытыми окнами.
--                  Предпочтительно использовать именно его. Не работает с некоторыми приложениями.
--                  Для корректной работы может потребоваться задать хендл родительского окна.
-- адрес_картинки - Адрес изображения в формате bmp 24 бита.
--                  "my_image.bmp" - изображение рядом с exe пилота.
--                  "folder\\my_image.bmp" - изображение в папке folder рядом с exe пилота
--                  "\\my_image.bmp" - изображение в корне диска, на котором лежит пилот.
--                  [[d:\uopilot\images\my_image.bmp]] - абсолютный путь.
--                  Учтите, что при задании адресов в lua символ '\' необходимо удваивать,
--                  либо заменять на '/', либо брать весь адрес в двойные квадртные скобки.
-- адрес_памяти,  - Поиск в ранее полученном изображении по средством функции getimage()
-- высота_изобр,    Указывается адрес битовой маски, высота изображения, ширина и количество
-- ширина_изобр,    байт на каждую строку. Из-за выравнивания размер строки может быть
-- длина.           не кратным битности изображения. Данный параметр так же используется
--                  для определения формата битовой маски (24 бита либо 24 бита цвет + 8 резерв).
--
-- [count]
-- Количество искомых изображений. 0 | -1 - найти все.
--
-- [deviation]
-- Допустимые отклонения цвета.
-- Синтаксис:
-- deviation_general | {blue, green, red} |
-- {blue_bottom, green_bottom, red_bottom, blue_upper, green_upper, red_upper}
-- Отклонения цвета может быть задано одним числом на все каналы в + и в -,
-- либо на каждый канал отдельно,
-- либо на каждый канал отдельно и отдельно нижняя и верхняя граница канала.
--
-- [deviation_type]
-- Тип расчета допустимого отклонения цвета. Значение по умолчанию "r".
-- Возможные значения:
-- "a" - absolute. Абсолютное отклонение канала.
--       Например, при цвете 50 100 200 и абсолютном отклонении 10,
--       допустимый диапазон цветов будет равен 40-60, 90-110, 190-210
-- "r" - relative. Относительное отклонение, задается в процентах.
--       Например, при цвете 50 100 200 и относительном отклонении 10,
--       допустимый диапазон цветов будет равен 45-55 90-110 180-220.
--       Округление происход в сторону расширения диапазона.
--       Например, при значении канала 101 и допустимом отклонении 10%,
--       допустимыми значениями канала будут 101-11=90 101+11=112, т.е. 90-112.
-- "s" - shadow. Затемнение/осветление. Рассчитывается соотношение каналов, задается в процентах.
--       Данный метод может быть полезен, например, при смене суток в игре.
--       В рамках данного метода цвет 50 100 200 и цвет 25 50 100 - будут полностью идентичны.
--       Для указанных цветов: 200/50=4 50/100=0.5 100/200=0.5
--                             100/25=4  25/50=0.5  50/100=0.5
--       При допустимом отклонении в 10, будут считаться допустимыми соотношения каналов:
--       3.6-4.4 0.45-0.55 0.45-0.55
--
-- [abs_flag]
-- Флаг указывающий на то, что изображение должно быть получено не относительно с окна
-- к которому произведена привязка пилота через Ctrl+A или workwindow,
-- а относительно левого верхнего угла экрана.
-- Актуально для method 1, 2.]====]

ext.findcolor = function(x1, y1, x2, y2, c, method, count, deviation, deviation_type, abs_crds)
local t = os.clock()
    if  type(x1) == "table" then
        abs_crds       = count
        deviation_type = method
        deviation      = c
        count          = y2
        method         = x2
        c              = y1    
    end
--log(1, os.clock() - t)    
    c                  = type(c) == "table" and c or {c}
    method             = method or workwindow()
    deviation          = internal.findcolor_deviation_parse(deviation)
    deviation_type     = deviation_type or "r"
--log(2, os.clock() - t)    
    local compare_func
    if deviation_type == "r" then
        compare_func = internal.color_deviation_r
    elseif deviation_type == "a" then
        compare_func = internal.color_deviation_a
    elseif deviation_type == "s" then
        compare_func = internal.color_deviation_s
    end
--log(3, os.clock() - t)    

    local offset_x1, offset_y1, offset_y1, offset_y2 = 0, 0, 0, 0
    local a, w, h, l
    if type(method) == "table" then
        a, w, h, l = method[1], method[2], method[3], method[4]
    elseif type(method) == "number" then
        a, w, h, l = getimage (x1, y1, x2, y2, method, abs_crds) -- getimage игнорирует x2, y2
        offset_x2 = w -    math.min(x2+1, w)  -- getimage игнорирует x2, y2
        offset_y2 = h - math.min(y2+1, h)  -- getimage игнорирует x2, y2
        saveimage(a,"image\\check.bmp")
    elseif type(method) == "string" then
        a, w, h, l = loadimage (method)
        offset_x1 =     math.min(x1,   w)
        offset_y1 =     math.min(y1,   h)
        offset_x2 = w -    math.min(x2+1, w)
        offset_y2 = h - math.min(y2+1, h)
    end
--log(4, os.clock() - t)    
    if not a then
        log("capture failed")
        stop_script()
    end
    log(a, w, h, l)
    
    local cc = internal.parse_split_color_to_min_max_bgr(c)

    local d = ffi.new("uint8_t[6]")
    d[0], d[1], d[2], d[3], d[4], d[5] = internal.findcolor_deviation_parse(deviation, d)


    local t = os.clock()
    
    log(a + offset_y1*l, a+(h-offset_y2)*l-1, l)
    
    local r = {}
    if deviation then
        for i = a + offset_y1*l, a+(h-offset_y2)*l-1, l do
            local y = i
            --p = zp + pa[0] + i / 3
            --log(222, tostring(p))
            --stop_script()
            for i = i+offset_x1*3, i+l-offset_x2*3-1, 3 do
                for j = 1, #c do    
                
                    --log(cc[j][0], cc[j][1], cc[j][2], cc[j][3], cc[j][4], cc[j][5], rmem("unsigned char*",i)[0],rmem("unsigned char*",i+1)[0],rmem("unsigned char*",i+2)[0], d[0], d[1], d[2], d[3], d[4], d[5])

                    --if  cc[j][0] - d[0] <= rmem("unsigned char*",i)[0] and cc[j][1] - d[1] <= rmem("unsigned char*",i)[1] and cc[j][2] - d[2] <= rmem("unsigned char*",i)[2] and
                     --   cc[j][3] + d[3] >= rmem("unsigned char*",i)[0] and cc[j][4] + d[4] >= rmem("unsigned char*",i)[1] and cc[j][5] + d[5] >= rmem("unsigned char*",i)[2] then
                    
                    --log((i-y)/3 + 1, (y-a)/l/3 + 1)
                    
                    if compare_func(cc[j][0], cc[j][1], cc[j][2], cc[j][3], cc[j][4], cc[j][5], rmem("unsigned char*",i)[0],rmem("unsigned char*",i)[1],rmem("unsigned char*",i)[2], d[0], d[1], d[2], d[3], d[4], d[5]) then                    
                        r[#r+1] = {}
                        r[#r][1] = (i-y)/3
                        r[#r][2] = math.floor((y-a)/l)
                        r[#r][3] = cc[j][1]*256*256 + cc[j][2]*256 + cc[j][3]
                        r[#r][4] = cc[j][4]*256*256 + cc[j][5]*256 + cc[j][6]
                        --log(r[#r][1],r[#r][2])
                        if count == #r then
                            return r
                        end
                    end
                end
                --p = p + 1
            end
        end
    else
        for y = 1, w do
            for x = 1, h do
                for i = 1, #deviation do
                    
                    if deviation_func() then
                    
                    end
                end
            end
        end
    end




--[[
    local pa = ffi.new("unsigned int[1]",a)
--local zp = ffi.new("unsigned char *")
    local p  = ffi.new("unsigned char[3]")

    local p = ffi.new("unsigned char *")
    p = p+pa[0]

--log(a)
--log(222, tostring(p))
--stop_script()
--log(333, #c)
    
--log(7, os.clock() - t)

    --ext.lg(d)
    --end_script()
    
--log(333, #c)    

--log(8, os.clock() - t)
local t = os.clock()
--log(l)
    local r = {}
    if deviation then
        for i = 0, h*l-1, l do
            local y = i
            --p = zp + pa[0] + i / 3
            --log(222, tostring(p))
            --stop_script()
            for i = i, i+w*3-1, 3 do
                for j = 1, #c do    
                --log(i)
                    --log(cc[j][0], cc[j][1], cc[j][2], cc[j][3], cc[j][4], cc[j][5], p[0], p[1], p[2], d[1], d[2], d[3], d[4], d[5], d[6])
                    --if compare_func(cc[j][0], cc[j][1], cc[j][2], cc[j][3], cc[j][4], cc[j][5], p[0], p[1], p[2], d[1], d[2], d[3], d[4], d[5], d[6]) then
                    --log(cc[j][0], cc[j][1], cc[j][2], cc[j][3], cc[j][4], cc[j][5], p[i], p[i+1], p[i+2], d[1], d[2], d[3], d[4], d[5], d[6])
                    if compare_func(cc[j][0], cc[j][1], cc[j][2], cc[j][3], cc[j][4], cc[j][5], p[i], p[i+1], p[i+2], d[1], d[2], d[3], d[4], d[5], d[6]) then                    
                        r[#r+1] = {}
                        r[#r][1] = (i-y)/3 + 1
                        r[#r][2] = (y)/l + 1
                        r[#r][3] = cc[j][1]*256*256 + cc[j][2]*256 + cc[j][3]
                        r[#r][4] = cc[j][4]*256*256 + cc[j][5]*256 + cc[j][6]  
                        --log(r[#r][1],r[#r][2])
                    end
                end
                --p = p + 1
            end
        end
    else
        for y = 1, w do
            for x = 1, h do
                for i = 1, #deviation do
                    
                    if deviation_func() then
                    
                    end
                end
            end
        end
    end
]]
    
deleteimage = internal.deleteimage
speed = speed + os.clock() - t
catch = #r
    
    return r
end


return ext


Цитата
Да, кстати. Что-то у меня не получилось сохранить картинку твоим имиджем. Что не так делаю? Кинь конкретный примерчик.

Дык я их и не сохранял =) Там где-то в отладке под старый getimage был saveimage. Скринилку пока не трогал.
Я тупо поставил в пеинте точки по углам и смотрел находит или нет (ну и в центре пару).

Если надо для отладки, то можно расскоментировать строку
--log(cc[j][0], cc[j][1], cc[j][2], cc[j][3], cc[j][4], cc[j][5], rmem("unsigned char*",i)[0],rmem("unsigned char*",i+1)[0],rmem("unsigned char*",i+2)[0], d[0], d[1], d[2], d[3], d[4], d[5])
Там покажет какие цвета передаются по каналам, какой цвет сравнивается, значения deviation.
Ну и можно еще расскоментить
--log(r[#r][1],r[#r][2])
будет при нахождении сразу показвать точки, но я для этого ext.lg обычно использовал. ext.lg - в лог пишет весь массив.


--------------------
Скрипты UOPilot под заказ.
Консультации по UOpilot 15$/час.
Услуги Lua разработчика (не пилот, проекты, постоянка)
Disсоrd:
Kov____
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения

Сообщений в этой теме
DarkMaster   Разработка findcolor, findimage   24.3.2021, 18:01
sutra   Я в теме. Я давно отказался от передачи массивов. ...   25.3.2021, 16:34
DarkMaster   Ловлю на слове. Пока хочу допилить, то, что есть,...   25.3.2021, 17:12
sutra   Не помню сколько у меня на фул хд. Я же сказал при...   25.3.2021, 17:28
DarkMaster   Ты где тут нашел адекватного?) Ну а вообще тесты ...   25.3.2021, 17:28
sutra   Да я понял, но у меня в основном нагрузка на файнд...   25.3.2021, 17:42
DarkMaster   По поводу создания изображений и помощи валенкам у...   25.3.2021, 17:50
DarkMaster   Из забавного. Речь пойдет о чтении из памяти данны...   26.3.2021, 0:34
sutra   Ну вот, зачем спрашивается лопатить фул хд. Разбил...   26.3.2021, 16:43
DarkMaster   ну вообще типа да, но типа нет. Поуму нужно делать...   26.3.2021, 16:49
sutra   rmem ("unsigned char*",i)[2] Я собствен...   26.3.2021, 17:07
DarkMaster   Автор Cirus --lua local ffi = require("ffi...   26.3.2021, 17:31
sutra   Понял лишь в общих чертах. Вопрос, а в файл сохран...   26.3.2021, 17:58
DarkMaster   Вот этот момент не совсем ясен. Почему 0 0? Почем...   26.3.2021, 18:00
sutra   Я правильно понимаю, что мне надо добавить возврат...   26.3.2021, 18:11
DarkMaster   Пока кроме скорости ничего не тестил, по идее он в...   26.3.2021, 18:15
sutra   ОК. Буду ждать новостей. Cirus-у отдельное БОЛЬШОЕ...   26.3.2021, 18:16
cirus   Потому что 0 0 это координаты куда скопировать из...   27.3.2021, 1:59
DarkMaster   Накидал кучу вопросов Cirus'у и надеюсь, что о...   27.3.2021, 11:41
DarkMaster   Собственно то, как вот оно есть. -- findcolor -- Ф...   27.3.2021, 13:42
cirus   --lua local ffi = require("ffi") ...   27.3.2021, 21:21
sutra   Дарк, прочитал мануал. Что точно нужно добавить - ...   28.3.2021, 10:15
sutra   Для чего нужен шаг? Например для поиска активной р...   28.3.2021, 10:41
DarkMaster   Как весело провести вечер и утро. А знаете ли вы,...   28.3.2021, 12:31
sutra   Попробовал новый getimage. Работает намного быстре...   28.3.2021, 13:43
DarkMaster   А максимума нет. Размер окна может быть намного б...   28.3.2021, 13:54
sutra   Насколько я понимаю, по уму надо бы возвращать адр...   28.3.2021, 13:59
DarkMaster   Я так и делаю. Все скоро будет =)   28.3.2021, 14:03
DarkMaster   Бэкапу пару дней. !@#$ notepad++   28.3.2021, 23:12
sutra   А тут как дела? Подвижки есть?   29.3.2021, 15:11
DarkMaster   Есть, откатился из-за чудес выше до момента пока ...   29.3.2021, 15:51
DarkMaster   Захват изображения. Вот так вроде похоже на правду...   29.3.2021, 17:09
Cockney   Ну и идейно я делаю замену пилотовских функций с ...   29.3.2021, 20:33
DarkMaster   Планов очень много, идей очень много. Я очень не ...   29.3.2021, 21:00
Cockney   Планов очень много, идей очень много. Я очень не ...   29.3.2021, 23:47
DarkMaster   Если угодно - сглазить не хочу. Блокнот реально по...   29.3.2021, 23:55
sutra   Ну вот, я явился возмутителем спокойствия и благод...   30.3.2021, 11:51
sutra   Попробовал сохранить картинку. Ничего не получилос...   30.3.2021, 13:16
cirus   Это начало bmp файла BM. Указать другую папку, в...   30.3.2021, 13:43
sutra   Создаёт файл 14 байт. Доступ к нему действительно ...   30.3.2021, 15:31
sutra   Последовательно пишу заголовок. Перегружаю Пилот, ...   30.3.2021, 15:44
sutra   Дарк, что-то я не понял как пользоваться твоим ими...   30.3.2021, 17:38
DarkMaster   Значит так. Версия из активной разработки. Дальше ...   30.3.2021, 17:38
DarkMaster   --lua local ffi=require "ffi" local rmem=...   30.3.2021, 17:46
sutra   Ни хрена себе ты наворочал. Тут месяц надо разбира...   30.3.2021, 17:47
DarkMaster   ext.lg - перекочевало из другого скрипта, в рамках...   30.3.2021, 17:47
sutra   Конечно моё мнение субъективно. Но вот зачем вообщ...   30.3.2021, 18:16
DarkMaster   Идейно это был изначально возврат к пилотовскому:...   30.3.2021, 18:19
sutra   Может не доглядел (тогда ткни меня носом), но не н...   30.3.2021, 18:34
DarkMaster   По разности каналов не делал. В достаточно большой...   30.3.2021, 18:41
sutra   Да я всё понимаю. Поэтому и не берусь претендовать...   30.3.2021, 18:43
DarkMaster   Если есть любые идеи, как оно должно быть - готов ...   30.3.2021, 18:43
sutra   Да, кстати. Что-то у меня не получилось сохранить ...   30.3.2021, 18:45
sutra   Вот объясните мне почему так? Просто хочу понять, ...   30.3.2021, 20:15
DarkMaster   Это является флагом писать строки сверху-вниз или...   30.3.2021, 20:18
sutra   Спасибо, ну примерно так и подозревал. Плохо ничег...   30.3.2021, 20:22
DarkMaster   Ну да, самое крутое не знать и писать. Думаешь я ...   30.3.2021, 20:25
sutra   Соответственно 32 битовая модель не требует контро...   30.3.2021, 20:30
Madeus   speed = speed + os.clock() - t Лишняя строчка?)   30.3.2021, 20:32
sutra   Эх! Понять бы ещё почему у меня проблемы с зап...   30.3.2021, 20:36
DarkMaster   бенчмарк. Ну для релиза лишняя, для работы не сов...   30.3.2021, 20:42
sutra   Перегруз не помог. Нарушается у меня доступ к запи...   30.3.2021, 20:44
Madeus   бенчмарк. Ну для релиза лишняя, для работы не сов...   30.3.2021, 20:59
DarkMaster   Можно удалить. Мой код тестов: speed = 0 catch = 0...   30.3.2021, 21:08
Madeus   Если не указать [deviation] вылетает с ошибкой .lu...   30.3.2021, 21:19
DarkMaster   чуть выше писал, что на данный момент только со в...   30.3.2021, 21:27
Madeus   У меня одного если не указать "abs" то и...   30.3.2021, 22:51
DarkMaster   Какой метод при поиске указан? При методе 2 будет...   31.3.2021, 0:00
Madeus   Какой метод при поиске указан? При методе 2 будет...   31.3.2021, 0:12
DarkMaster   Это сделано исключительно для совместимости со ста...   31.3.2021, 0:23
DarkMaster   Sutra, я тут в итоге все-таки наткнулся на один уж...   31.3.2021, 0:45
DarkMaster   Кстати низя. Ты никак диапазоном не задашь, что r...   31.3.2021, 2:06
Madeus   Метод 2, тогда понятно, хотя надо проверить скоро...   31.3.2021, 2:06
DarkMaster   В обоих случаях зоны имели одинаковые цвета? Мето...   31.3.2021, 2:43
cirus   Сделать скрин и искать на скрине, быстрее будет.   31.3.2021, 3:01
DarkMaster   100 прогонов во всех тестах Фулл хд. Абс выкл. r ...   31.3.2021, 3:06
Madeus   В целом абс существенным образом не повлияло на о...   31.3.2021, 17:20
sutra   Спасибо Дарк. Конечно так я и сам могу, но по при...   31.3.2021, 11:27
DarkMaster   Я его код не тестил. Мне скрины на тот момент были...   31.3.2021, 13:03
DarkMaster   Накидал скринилку. Фиксировные битовые константы з...   31.3.2021, 17:44
Madeus   Только в случае, если используется метод 2 или ме...   31.3.2021, 17:51
sutra   Тест старого и нового имиджа по хендлу зона old ...   31.3.2021, 17:59
DarkMaster   Круто я когда-то лажанул. Убрал объявление getimag...   31.3.2021, 18:07
Madeus   Круто я когда-то лажанул. Убрал объявление getima...   31.3.2021, 18:14
sutra   Хотя тестить в lua - гиблое дело. Можно лишь прибл...   31.3.2021, 18:12
DarkMaster   getimage 100 итераций вызов + удаление изображения...   31.3.2021, 18:44
sutra   Дарк, спасибо за скринилку. Всё, на сегодня хватит...   31.3.2021, 19:05
DarkMaster   На самом деле там проблема только одна - он делае...   31.3.2021, 19:23
Madeus   Нужно добавить возврат координат найденного цвета,...   31.3.2021, 22:41
DarkMaster   Функция возвращает таблицу найденных цветов: x y ц...   31.3.2021, 23:23
Madeus   Проблема в том что она возвращает x y относительно...   1.4.2021, 0:11
DarkMaster   Вот для этого тесты и есть =) Поправлю. Спасибо.   1.4.2021, 0:12
Madeus   Супер, спасибо за труды! :) Ждем findimage B)   1.4.2021, 0:17
DarkMaster   1)+ Переделать метод 0 для поиска по относительным...   1.4.2021, 2:12
Madeus   У меня до сих пор тяжелые думы по поводу шага пои...   1.4.2021, 2:35
DarkMaster   Хмм.. Вообще я не то залил, но этот фикс вроде но...   1.4.2021, 2:49
cirus   За всё время шаг поиска использовал только 1 раз. ...   1.4.2021, 3:02
Madeus   То ли лыжы не едут то ли спать пора. В общем что у...   1.4.2021, 3:04
DarkMaster   И то и другое. Спать пора - я не ту версию залил,...   1.4.2021, 3:19
6 страниц V  1 2 3 > » 


Ответить в эту темуОткрыть новую тему
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

- Текстовая версия | Версия для КПК Сейчас: 24.6.2025, 22:49
Designed by Nickostyle