18834161486 发表于 2023-11-2 16:17

纯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 + tw / 2 + x1, minLoc + th / 2 + y1
      else:
            return -1, -1

    def Hex_to_Rgb(self, hex):
      '''
      十六进制转RGB
      :param hex: 十六进制颜色值
      :return: RGB
      '''
      return np.array(tuple(int(hex, 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
      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[:, ]

    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()
      for i in des.split(','):
            rgb_y = i[-13:]
            r = int(rgb_y, 16)
            g = int(rgb_y, 16)
            b = int(rgb_y, 16)
            y = int(rgb_y[-2:])
            rgby.append()
      for i in range(1, len(des.split(','))):
            ps.append(.split('|')), int(des.split(',').split('|'))])
      for i in rgby:
            result = np.logical_and(abs(img[:, :, 0:1] - i) < i, abs(img[:, :, 1:2] - i) < i,
                                    abs(img[:, :, 2:3] - i) < i)
            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 = int(index) - ps
                  index = int(index) - ps
                q = set()
                w = set()
                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 + (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(.pt for m in good]).reshape(-1, 1, 2)
            dst_pts = np.float32(.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([, , , ]).reshape(-1, 1, 2)
            dst = cv2.perspectiveTransform(pts, M)
            res = (dst + dst) / 2# [[[ 39.11337147.11575 ]] []
            return int(res) + x1, int(res) + 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
            argi = argj.T
            pt = argj)]
            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 + tw / 2 + x1, minLoc + 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 = for i in dess]
      des =
      pds = for i in dess]
      pds = tuple(tuple(int(item) 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, axis=-1)
      new_img = np.where(mask[..., None], , ) 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()

mebyan 发表于 2023-11-2 23:23

为什么我运行代码后,只是出现一个黑色屏幕,仅上面和左侧有指甲大小区域内的一点蓝色的微不可察的蛛丝马迹?

chaozhi 发表于 2023-11-2 16:49

楼主厉害,学习学习

vethenc 发表于 2023-11-2 17:23

非常厉害,感谢分享,实用性很大

rushuimuyu 发表于 2023-11-2 17:48

感谢楼主分享

ghwanz 发表于 2023-11-2 18:28

无图无真相

18834161486 发表于 2023-11-3 07:43

mebyan 发表于 2023-11-2 23:23
为什么我运行代码后,只是出现一个黑色屏幕,仅上面和左侧有指甲大小区域内的一点蓝色的微不可察的蛛丝马迹 ...

现在就只调用了stressshow这个方法,其他方法调用可以在B站搜萌新本炘,有录过教程

wzmmc 发表于 2023-11-3 08:14

66666666666

lingwushexi 发表于 2023-11-3 09:09

感谢楼主分享

kings0b 发表于 2023-11-3 13:26

感谢楼主分享学习学习
页: [1] 2 3 4 5
查看完整版本: 纯python实现大漠图色功能