File size: 4,206 Bytes
2ad5883
 
 
 
b4c89f9
 
 
 
 
 
 
 
2ad5883
7c3f871
b9177b9
 
 
3d6ae23
2ad5883
b4c89f9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9da2db4
37a0d36
 
 
 
 
 
 
 
 
 
 
0773ca1
7242758
 
37a0d36
 
 
0773ca1
37a0d36
b4c89f9
 
 
 
9da2db4
2ad5883
b9177b9
 
2ad5883
b9177b9
 
 
2ad5883
b9177b9
 
 
 
2ad5883
 
 
 
b9177b9
2ad5883
 
 
 
 
 
 
b9177b9
 
 
b4c89f9
 
0773ca1
b4c89f9
b9177b9
 
 
9da2db4
4c1d7f9
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
116
117
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')
mobilenet = MobileNetV2(weights="imagenet", include_top=False, pooling='avg')

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)) * 100
            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 round(score) if 0 < score < 1 else 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)
            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
            similarity_mobilenet_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