#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File        :   qr_orb.py    
@Contact     :   zpyovo@hotmail.com
@License     :   (C)Copyright 2018-2019, Lab501-TransferLearning-SCUT
@Description :

@Modify Time      @Author    @Version    @Desciption
------------      -------    --------    -----------
2023/8/26 18:58   Pengyu Zhang      1.0         None
'''

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import cv2
import numpy as np

def preprocess_image(image):
    # 将图像调整为固定大小
    image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    resized_image = cv2.resize(image, (275, 275), interpolation=cv2.INTER_NEAREST)
    return resized_image

def FAST_corner_detection(image, threshold):
    keypoints = []
    for i in range(3, image.shape[0] - 3):
        for j in range(3, image.shape[1] - 3):
            center_pixel = image[i, j]
            pixel_difference = [abs(image[i + dx, j + dy] - center_pixel) for dx, dy in
                                [(0, -3), (0, 3), (-3, 0), (3, 0)]]
            if all(diff > threshold for diff in pixel_difference):
                keypoints.append(cv2.KeyPoint(j, i, 7))
    return keypoints


def BRIEF_descriptor(keypoints, image):
    patch_size = 31
    descriptors = []
    for kp in keypoints:
        x, y = int(kp.pt[0]), int(kp.pt[1])
        patch = image[y - patch_size // 2:y + patch_size // 2 + 1, x - patch_size // 2:x + patch_size // 2 + 1]
        descriptor = ""
        for i in range(patch_size * patch_size):
            x1, y1 = np.random.randint(0, patch_size, size=2)
            x2, y2 = np.random.randint(0, patch_size, size=2)
            if patch[y1, x1] < patch[y2, x2]:
                descriptor += "0"
            else:
                descriptor += "1"
        descriptors.append(descriptor)
    return descriptors


def ORB(image, nfeatures=500, fastThreshold=20):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    keypoints = FAST_corner_detection(gray, fastThreshold)
    keypoints = sorted(keypoints, key=lambda x: -x.response)[:nfeatures]

    descriptors = BRIEF_descriptor(keypoints, gray)

    return keypoints, descriptors

def ORB_detect(img,nfeatures=800,fastThreshold=20):
    img = preprocess_image(img)
    # 初始化opencv原生ORB检测器
    orb = cv2.ORB_create(nfeatures=nfeatures, scaleFactor=1.2, edgeThreshold=31, patchSize=31, fastThreshold=fastThreshold)

    kp, des = orb.detectAndCompute(img, None)
    return des


'''
必要传参：
    std_roi_feature: 服务器备案特征数据
    ter_roi_feature: 手机终端特征数据
    threshold: 相似度对比阈值
预留传参：
    distance: 距离筛选度量，默认值100
'''

def roi_siml(std_roi_feature,ter_roi_feature,distance=100, threshold = None):

    std_roi_feature = std_roi_feature.astype('uint8')
    ter_roi_feature = ter_roi_feature.astype('uint8')
    threshold = float(threshold)

    # 使用汉明距离对特侦点距离进行计算
    bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=False)
    # 使用knn算法进行匹配
    matches = bf.knnMatch(std_roi_feature, trainDescriptors=ter_roi_feature, k=2)

    # 去除无效和模糊的匹配
    good = []
    for match in matches:
        if len(match) >= 2:
            good = [(m, n) for (m, n) in matches if m.distance < 0.95 * n.distance and m.distance < distance]

    similarity = len(good) / len(matches) *100
    if similarity >=threshold:
        return 'passed',similarity
    else:
        return 'failed ',similarity




