File size: 4,421 Bytes
2ad5883
 
 
 
b4c89f9
 
 
 
 
 
 
 
2ad5883
7c3f871
b9177b9
 
 
3d6ae23
2ad5883
b4c89f9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274bce3
b4c89f9
 
 
 
 
 
 
 
 
274bce3
b4c89f9
 
 
 
 
274bce3
37a0d36
 
 
 
 
 
 
 
 
 
 
0773ca1
7242758
274bce3
37a0d36
 
 
06cdb0c
37a0d36
b4c89f9
 
 
 
9da2db4
2ad5883
b9177b9
 
2ad5883
b9177b9
 
 
2ad5883
b9177b9
 
 
 
2ad5883
 
 
 
b9177b9
2ad5883
 
 
 
 
 
 
b9177b9
 
 
b4c89f9
 
c7afcdf
 
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, img1AssetCode, img2AssetCode):
    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 from {img1AssetCode} and {img2AssetCode} 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, img1AssetCode, img2AssetCode):
    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 from {img1AssetCode} and {img2AssetCode} is {score}")
    except Exception as e:
        logging.error("Erro ao verificar similaridade ORB", exc_info=True)

    return 1 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, images[0].assetCode, images[i].assetCode)
            similarity_mobilenet_score = mobilenet_sim(original_image, image, images[0].assetCode, images[i].assetCode)
        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