找回密码
  注册[Register]
查看: 261|回复: 2

[python] 纯python实现大漠图色功能

[复制链接]
发表于 2023-11-2 19:09 | 显示全部楼层 |阅读模式
禁止求评分、诱导评分、互刷评分、互刷悬赏值,违规者封号处理。
禁止发布推广、邀请码、邀请链接、二维码或者有利益相关的任何推广行为。
所有非原创软件请发布在【精品软件区】,发帖必须按照本版块版规格式发帖。

[Python] 纯文本查看 复制代码
# 更新StressShow命令
 
import numpy as np
import pyautogui
import copy
import cv2
from sklearn import cluster
 
 
class TuSe:
    def __init__(self):
        print('欢迎使用')
 
    def GetCapture(self, stax, stay, endx, endy):
        w = endx - stax
        h = endy - stay
        im = pyautogui.screenshot(region=(stax, stay, w, h))
        # im = cv2.cvtColor(np.array(im), cv2.COLOR_BGR2RGB)
        return np.array(im)
 
    def FindPic(self, x1, y1, x2, y2, path, thd):
        '''
        找图
        :param x1: 起点X
        :param y1: 起点Y
        :param x2: 终点X
        :param y2: 终点Y
        :param path: 图片路径
        :param thd: 相似度
        :return: 图片中心坐标
        '''
        img = self.GetCapture(x1, y1, x2, y2)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        template = cv2.imread(path, 0)
        th, tw = template.shape[::]
        rv = cv2.matchTemplate(img, template, 1)
        minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(rv)
        if 1 - minVal >= thd:
            return minLoc[0] + tw / 2 + x1, minLoc[1] + th / 2 + y1
        else:
            return -1, -1
 
    def Hex_to_Rgb(self, hex):
        '''
        十六进制转RGB
        :param hex: 十六进制颜色值
        :return: RGB
        '''
        return np.array(tuple(int(hex[i:i + 2], 16) for i in (0, 2, 4)))
 
    def CmpColor(self, x, y, color, sim: float):
        '''
        比色
        :param x: X坐标
        :param y: Y坐标
        :param color: 十六进制颜色,可以从大漠直接获取
        :param sim: 相似偏移
        :return: 真或加
        '''
        img = self.GetCapture(x - 1, y - 1, x + 1, y + 1)
        img = np.array(img)
        img = img[1][1]
        color = self.Hex_to_Rgb(color)
        res = np.absolute(color - img)
        sim = int((1 - sim) * 255)
        return True if np.amax(res) <= sim else False
 
    def FindColor(self, x1, y1, x2, y2, des, sim: float):
        '''
        找色
        :param x1: 起点X
        :param y1: 起点Y
        :param x2: 终点X
        :param y2: 终点Y
        :param des: 十六进制颜色,可以从大漠直接获取
        :param sim: 相似偏移
        :return:
        '''
        img = self.GetCapture(x1, y1, x2, y2)
        img = np.array(img)
        res = np.absolute(img - self.Hex_to_Rgb(des))
        sim = int((1 - sim) * 255)
        res = np.argwhere(np.all(res <= sim, axis=2))
        res = res + (y1, x1)
        return res[:, [1, 0]]
 
    def GetColorNum(self, x1, y1, x2, y2, des, sim: float):
        '''
        获取颜色数量
        :param x1: 起点X
        :param y1: 起点Y
        :param x2: 终点X
        :param y2: 终点Y
        :param des: 十六进制颜色,可以从大漠直接获取
        :param sim: 相似偏移
        :return:
        '''
        return len(self.FindColor(x1, y1, x2, y2, des, sim))
 
    def FindMultColor(self, stax, stay, endx, endy, des):
        '''
        多点找色
        :param stax:
        :param stay:
        :param endx:
        :param endy:
        :param des: 大漠获取到的多点找色数据,偏色必须写上
        :return:
        '''
        w = endx - stax
        h = endy - stay
        img = pyautogui.screenshot(region=(stax, stay, w, h))
        img = np.array(img)
        rgby = []
        ps = []
        a = 0
        firstXY = []
        res = np.empty([0, 2])
        for i in des.split(','):
            rgb_y = i[-13:]
            r = int(rgb_y[0:2], 16)
            g = int(rgb_y[2:4], 16)
            b = int(rgb_y[4:6], 16)
            y = int(rgb_y[-2:])
            rgby.append([r, g, b, y])
        for i in range(1, len(des.split(','))):
            ps.append([int(des.split(',')[i].split('|')[0]), int(des.split(',')[i].split('|')[1])])
        for i in rgby:
            result = np.logical_and(abs(img[:, :, 0:1] - i[0]) < i[3], abs(img[:, :, 1:2] - i[1]) < i[3],
                                    abs(img[:, :, 2:3] - i[2]) < i[3])
            results = np.argwhere(np.all(result == True, axis=2)).tolist()
            if a == 0:
                firstXY = copy.deepcopy(results)
            else:
                nextnextXY = copy.deepcopy(results)
                for index in nextnextXY:
                    index[0] = int(index[0]) - ps[a - 1][1]
                    index[1] = int(index[1]) - ps[a - 1][0]
                q = set([tuple(t) for t in firstXY])
                w = set([tuple(t) for t in nextnextXY])
                matched = np.array(list(q.intersection(w)))
                res = np.append(res, matched, axis=0)
            a += 1
        unique, counts = np.unique(res, return_counts=True, axis=0)
        index = np.argmax(counts)
        re = unique[index] + (stay, stax)
        if np.max(counts) == len(des.split(',')) - 1:
            return np.flipud(re)
        return np.array([-1, -1])
 
    def FindPicEx(self, x1, y1, x2, y2, path, thd=0.9, MIN_MATCH_COUNT=8):
        '''
        全分辨率找图
        :param x1:
        :param y1:
        :param x2:
        :param y2:
        :param path:
        :param thd: 相似度
        :param MIN_MATCH_COUNT: 特征点数量
        :return:
        '''
        thd = thd - 0.2
        template = cv2.imread(path, 0)  # queryImage
        # target = cv2.imread('target.jpg', 0)  # trainImage
        target = self.GetCapture(x1, y1, x2, y2)
        target = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY)
        # Initiate SIFT detector创建sift检测器
        sift = cv2.xfeatures2d.SIFT_create()
        # find the keypoints and descriptors with SIFT
        kp1, des1 = sift.detectAndCompute(template, None)
        kp2, des2 = sift.detectAndCompute(target, None)
        # 创建设置FLANN匹配
        FLANN_INDEX_KDTREE = 0
        index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
        search_params = dict(checks=50)
        flann = cv2.FlannBasedMatcher(index_params, search_params)
        matches = flann.knnMatch(des1, des2, k=2)
        # store all the good matches as per Lowe's ratio test.
        good = []
        for m, n in matches:
            if m.distance < thd * n.distance:
                good.append(m)
        if len(good) > MIN_MATCH_COUNT:
            # 获取关键点的坐标
            src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
            dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)
            # 计算变换矩阵和MASK
            M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
            h, w = template.shape
            # 使用得到的变换矩阵对原图像的四个角进行变换,获得在目标图像上对应的坐标
            pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)
            dst = cv2.perspectiveTransform(pts, M)
            res = (dst[0] + dst[2]) / 2  # [[[ 39.11337  147.11575 ]] [[135.06624  255.12143 ]]
            return int(res[0][0]) + x1, int(res[0][1]) + y1
        else:
            return -1, -1
 
    def _FilterRec(self, res, loc):
        """ 对同一对象的多个框按位置聚类后,按置信度选最大的一个进行保留。
        :param res: 是 cv2.matchTemplate 返回值
        :param loc: 是 cv2.np.argwhere(res>threshold) 返回值
        :return: 返回保留的点的列表 pts
        """
        model = cluster.AffinityPropagation(damping=0.5, max_iter=100, convergence_iter=10, preference=-50).fit(loc)
        y_pred = model.labels_
        pts = []
        for i in set(y_pred):
            argj = loc[y_pred == i]
            argi = argj.T
            pt = argj[np.argmax(res[tuple(argi)])]
            pts.append(pt[::-1])
        return np.array(pts)
 
    def FindMultPic(self, x1, y1, x2, y2, path, thd):
        '''
        多目标找图
        :param x1:
        :param y1:
        :param x2:
        :param y2:
        :param path:
        :param thd: 相似度
        :return:
        '''
        target = self.GetCapture(x1, y1, x2, y2)
        target = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY)
        template = cv2.imread(path, 0)
        w, h = template.shape[:2]
        res = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
        loc = np.argwhere(res >= thd)
        if len(loc):
            resc = self._FilterRec(res, loc)
            return resc + (h / 2 + x1, w / 2 + y1)
        else:
            return [[-1, -1]]
 
    def FindPic_TM(self, x1, y1, x2, y2, path, thd):
        '''
        找透明图,透明色为黑色
        :param x1: 起点X
        :param y1: 起点Y
        :param x2: 终点X
        :param y2: 终点Y
        :param path: 图片路径
        :param thd: 相似度
        :return: 图片中心坐标
        '''
        img = self.GetCapture(x1, y1, x2, y2)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        template = cv2.imread(path)
        template2 = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
        ret, mask = cv2.threshold(template2, 20, 255, cv2.THRESH_BINARY)
        th, tw = template.shape[:2]
        rv = cv2.matchTemplate(img, template, 1, mask=mask)
        minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(rv)
        if 1 - minVal >= thd:
            return minLoc[0] + tw / 2 + x1, minLoc[1] + th / 2 + y1
        else:
            return -1, -1
 
    def StressShow(self, stax, stay, endx, endy, des, type=0):
        '''
        保留选中颜色,其他为黑色,相似度根据偏色调整
        :param stax:
        :param stay:
        :param endx:
        :param endy:
        :param des: 大漠的色彩描述
        :param type: 0为原来颜色,1为白色
        :return:
        '''
        # des = 'e81010-101010|f9ad08-000000'
        dess = des.split('|')
        des = [i[0:6] for i in dess]
        des = [np.array(self.Hex_to_Rgb(d)) for d in des]
        pds = [i[-6:] for i in dess]
        pds = tuple(tuple(int(item[i:i + 2]) for i in range(0, len(item), 2)) for item in pds)
        img = self.GetCapture(stax, stay, endx, endy)
        mask = np.zeros(img.shape[:2], dtype=np.bool_)
        for i, color in enumerate(des):
            mask += np.all(np.abs(img - color) <= pds[i], axis=-1)
        new_img = np.where(mask[..., None], [255, 255, 255], [0, 0, 0]) if type else np.where(mask[..., None], img,
                                                                                              [0, 0,
                                                                                               0])  # 修改这里,将选中的颜色设为白色
        img_converted = cv2.convertScaleAbs(new_img)
        img_converted = cv2.cvtColor(np.array(img_converted), cv2.COLOR_BGR2RGB)
        return img_converted
 
 
a = TuSe()
b = a.StressShow(0, 0, 1920, 1080, 'e81010-101010|36659e-101010', 0)
cv2.imshow('13', b)
cv2.waitKey(0)
cv2.destroyAllWindows()

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2023-11-2 19:09 | 显示全部楼层
666666
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

发表于 2023-11-2 19:17 | 显示全部楼层
666666666666
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

RSS订阅|手机版|小黑屋|大牛论坛 |我的广告

GMT+8, 2024-4-28 04:36 , Processed in 0.037666 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表