python 大圖中找小圖所在坐標


對於不方便定位獲取的元素,可以通過圖像處理,查詢一張圖在另一張圖中的位置,然后獲取坐標,從而操作此元素。

譬如針對瀏覽器上某個按鈕,無法通過xpath等方式定位,可以截取此按鈕圖片,然后對瀏覽器截圖,通過圖片對比,獲取此按鈕坐標,然后點擊等。

from pathlib import Path
import numpy
import cv2


class Image:
    def __init__(self, image):
        self.image = cv2.imread(image, cv2.IMREAD_UNCHANGED)

    @property
    def width(self):
        return self.image.shape[1]

    @property
    def height(self):
        return self.image.shape[0]


class MatchImg(object):
    def __init__(self, source, template, threshod=0.95):
        """
        匹配一個圖片,是否是另一個圖片的局部圖。source是大圖,template是小圖。即判斷小圖是否是大圖的一部分。
        :param source:
        :param template:
        :param threshod: 匹配程度,值越大,匹配程度要求就越高,最好不要太小
        """
        self.source_img = source
        self.template_img = template
        self.threshod = threshod

    def match_template(self, method=cv2.TM_CCOEFF_NORMED):
        """
        返回小圖左上角的點,在大圖中的坐標。
        :param method:
        :return: list[tuple(x,y),...]
        """
        try:
            result = cv2.matchTemplate(self.source_img.image, self.template_img.image, method)
            locations = numpy.where(result >= self.threshod)
            res = list(zip(locations[1], locations[0]))  # 返回的是匹配到的template左上角那個坐標點在image中的位置,可能有多個值
            return res
        except cv2.error as e:
            print(e)

    def get_template_position(self):
        """
        獲取小圖在大圖中,左上角和右下角的坐標
        :return: List[list[x,y,x,y],...]
        """
        res = self.match_template()
        new_pos = []
        for r in res:
            r = list(r)
            r.append(r[0]+self.template_img.width)
            r.append(r[1]+self.template_img.height)
            new_pos.append(r)
        return new_pos

    def get_img_center(self):
        """
        獲取大圖中,每個小圖中心點所在的坐標
        :return:
        """
        pos = self.match_template()
        points = []
        for p in pos:
            x, y = p[0]+int(self.template_img.width/2), p[1]+int(self.template_img.height/2)
            points.append((x, y))
        return points


def load_image_file(path):
    path = Path(path)
    if not path.exists():
        print('not exist file')
    try:
        image = Image(str(path))
        return image
    except cv2.error as e:
        print(e)


if __name__ == "__main__":
    img1 = load_image_file('./images/app.png')
    img2 = load_image_file('./images/on.png')
    
    process = MatchImg(img1, img2, 0.96)
    points = process.get_img_center()
    print(points)



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM