File size: 4,048 Bytes
2ad5883
 
 
 
b4c89f9
 
 
 
 
 
 
 
2ad5883
7c3f871
b9177b9
 
 
2ad5883
b4c89f9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9da2db4
37a0d36
 
 
 
 
 
 
 
 
 
 
 
7242758
 
37a0d36
 
 
 
 
b4c89f9
 
 
 
9da2db4
2ad5883
b9177b9
 
2ad5883
b9177b9
 
 
2ad5883
b9177b9
 
 
 
2ad5883
 
 
 
b9177b9
2ad5883
 
 
 
 
 
 
b9177b9
 
 
b4c89f9
 
9da2db4
b4c89f9
b9177b9
 
 
9da2db4
b9177b9
e5555a2
b4c89f9
2ad5883
b9177b9
2ad5883
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import base64
import cv2
import numpy as np
import requests
import logging
from typing import List
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
from tensorflow.keras.models import Model
from tensorflow.keras.preprocessing.image import img_to_array
from sklearn.metrics.pairwise import cosine_similarity
from skimage.metrics import structural_similarity as ssim
from models import RequestModel, ResponseModel
from PIL import Image
from io import BytesIO

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

def preprocess_image_for_mobilenet(image):
    if len(image.shape) == 2:
        image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)
    elif image.shape[2] == 1:
        image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)
    else:
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

    image = cv2.resize(image, (224, 224))
    image = img_to_array(image)
    image = np.expand_dims(image, axis=0)
    image = preprocess_input(image)

    return image

def mobilenet_sim(img1, img2):
    try:
        img1_proc = preprocess_image_for_mobilenet(img1)
        img2_proc = preprocess_image_for_mobilenet(img2)

        feat1 = mobilenet.predict(img1_proc, verbose=0)
        feat2 = mobilenet.predict(img2_proc, verbose=0)

        sim = cosine_similarity(feat1, feat2)[0][0] 
        sim_score = (sim + 1) * 50 
        print(f"MobileNet similarity score is {sim_score}")
        return float(sim_score)
    except Exception as e:
        logging.error("Erro ao calcular similaridade com MobileNet", exc_info=True)
        return 0

def orb_sim(img1, img2):
    score = 0

    try:
        orb = cv2.ORB_create()
        kp_a, desc_a = orb.detectAndCompute(img1, None)
        kp_b, desc_b = orb.detectAndCompute(img2, None)
    
        bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
        matches = bf.match(desc_a, desc_b)
        similar_regions = [i for i in matches if i.distance < 20]
        if len(matches) > 0:
            score = len(similar_regions) / len(matches)
            if (score > 0):
                logging.info(f"Orb score is {score}")
    except Exception as e:
        logging.error("Erro ao verificar similaridade ORB", exc_info=True)

    return score

def ssim_sim(img1, img2):
    s, _ = ssim(img1, img2, full=True)
    return (s + 1) * 50


def load_image_url(source):
    Image.MAX_IMAGE_PIXELS = None

    if source.startswith('http'):
        response = requests.get(source)
        img = np.asarray(bytearray(response.content), dtype=np.uint8)
        img = cv2.imdecode(img, cv2.IMREAD_GRAYSCALE)
    else:
        img = base64.b64decode(source)
        img = Image.open(BytesIO(img))
        img = np.array(img)
        img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

    return img

def check_similarity(images: List[RequestModel]):
    logging.info(f"Checking similarity for main source with resource id {images[0].originId}")

    original_image = load_image_url(images[0].source)
    original_image_shape = original_image.shape

    results = []

    for i in range(1, len(images)):
        try:
            image = load_image_url(images[i].source)
            image = cv2.resize(image, original_image_shape[::-1])
        
            similarity_score = ssim_sim(original_image, image)
            similarity_orb_score = orb_sim(original_image, image) * 100
            similarity_mobilenet_score = mobilenet_sim(original_image, image)
        except Exception as e:
            logging.error(f"Error loading image for resource id {images[i].originId} : {e}")
            similarity_score = 0
            similarity_orb_score = 0

        response = ResponseModel(originId=images[i].originId, source=images[i].source, sequence=images[i].sequence,
                                 assetCode=images[i].assetCode, similarity=similarity_score, similarityOrb=similarity_orb_score, similarityMobileNet=similarity_mobilenet_score)
        results.append(response)

    return results