import cv2
import imutils
import numpy as np
from PIL.Image import Image

import utils.matplotlib


def match_resize(src: Image, tmpl: str, similarity=0.9, step=10, fast=False):
    src = cv2.cvtColor(np.asarray(src), cv2.COLOR_RGB2BGR)
    src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
    tmpl = cv2.imread(tmpl)
    tmpl_gray = cv2.cvtColor(tmpl, cv2.COLOR_BGR2GRAY)
    found = None
    tmp_r = 0
    for scale in np.linspace(0.2, 2, step)[::-1]:
        # 根据scale比例缩放图像，并保持其宽高比
        resized = imutils.resize(src_gray, width=int(src_gray.shape[1] * scale))
        r = src_gray.shape[1] / float(resized.shape[1])
        result = cv2.matchTemplate(resized, tmpl_gray, cv2.TM_CCOEFF_NORMED)
        found_location = convert_location(result, tmpl_gray, similarity, r)
        # 快速匹配, 如果缩放比例越大 相似度越低就直接退出循环 返回当前最佳结果
        if fast:
            if found is not None and found_location is not None:
                print(found[2], found_location[2])
                if tmp_r < r and found[2] > found_location[2]:
                    break
            tmp_r = r
        # 如果我们找到了一个新的最大校正值，更新簿记变量值
        if found is None or (
                found_location is not None and found_location[2] >= similarity and found_location[2] > found[2]):
            found = found_location
    if found is None:
        return None
    x, y, _ = found
    print("x,y (%s, %s)" % (x, y))
    return found[0], found[1]


def match(src: Image, tmpl: str, similarity=0.9):
    # cv::TM_CCOEFF_NORMED = 5 标准相关匹配
    method = cv2.TM_CCOEFF_NORMED
    src = cv2.cvtColor(np.asarray(src), cv2.COLOR_RGB2BGR)
    # 灰度图提高精度
    src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
    tmpl = cv2.imread(tmpl)
    tmpl_gray = cv2.cvtColor(tmpl, cv2.COLOR_BGR2GRAY)
    # print('imagetempl.shape:', tmpl_gray.shape)
    result = cv2.matchTemplate(src_gray, tmpl_gray, method)
    print(result)
    loc = convert_location(result, tmpl_gray, similarity)
    if loc is None:
        return
    x, y, _ = loc
    print("x,y (%s, %s)" % (x, y))
    return x, y


def convert_location(result, tmpl, similarity, resize=1):
    method = 5
    min_max = cv2.minMaxLoc(result)
    if method == 0 or method == 1:  # 根据不同的模式最佳匹配位置取值方法不同
        match_loc = min_max[2]
    else:
        match_loc = min_max[3]
    right_bottom = (match_loc[0] + tmpl.shape[1], match_loc[1] + tmpl.shape[0])
    # print('result.min_max:', min_max, 'method=', method)
    # print('match_loc:', match_loc, type(match_loc))
    # print('right_bottom', right_bottom, type(right_bottom))
    x = int(match_loc[0] * resize) + int((right_bottom[0] - match_loc[0]) / 2 * resize)
    y = int(match_loc[1] * resize) + int((right_bottom[1] - match_loc[1]) / 2 * resize)

    print("(%s, %s) 缩放比例: %s, 相似度: %s" % (x, y, resize, min_max[1]))
    if min_max[1] < similarity:
        return None
    return x, y, min_max[1]
