MarioPrzBasto commited on
Commit
38a2ef1
·
verified ·
1 Parent(s): 17c40a5

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +25 -158
main.py CHANGED
@@ -1,139 +1,29 @@
 
 
 
 
1
  import os
2
  import json
3
- from typing import List, Optional
4
- from fastapi import FastAPI, HTTPException, Form
5
- from fastapi.responses import JSONResponse
6
- from pydantic import BaseModel
7
  import cv2
8
  import numpy as np
9
- import httpx
10
 
11
- BASE_DIR = "/tmp/data"
12
  app = FastAPI()
13
 
14
- class RequestModel(BaseModel):
15
- originId: int
16
- originSource: str
17
- sequence: int
18
- assetCode: str
19
- source: str
20
- similarity: int
21
-
22
-
23
-
24
- def calcular_sift(img1, img2):
25
- """Calcula e compara características SIFT entre duas imagens."""
26
- try:
27
- sift = cv2.SIFT_create()
28
- kp1, des1 = sift.detectAndCompute(img1, None)
29
- kp2, des2 = sift.detectAndCompute(img2, None)
30
- if des1 is None or des2 is None:
31
- print("Erro: SIFT não encontrou descritores suficientes.")
32
- return 0
33
- bf = cv2.BFMatcher()
34
- matches = bf.knnMatch(des1, des2, k=2)
35
- good_matches = []
36
- for m, n in matches:
37
- if m.distance < 0.75 * n.distance:
38
- good_matches.append([m])
39
- return len(good_matches)
40
- except Exception as e:
41
- print(f"Erro ao calcular SIFT: {e}")
42
- return 0
43
-
44
-
45
- def calcular_surf(img1, img2):
46
- """Calcula e compara características SURF entre duas imagens."""
47
- try:
48
- # Verifica a versão do OpenCV para usar o módulo correto
49
- if hasattr(cv2, 'xfeatures2d'):
50
- surf = cv2.xfeatures2d.SURF_create()
51
- else:
52
- raise ImportError("Módulo 'cv2.xfeatures2d' não encontrado. Certifique-se de ter o opencv-contrib-python instalado.")
53
-
54
- kp1, des1 = surf.detectAndCompute(img1, None)
55
- kp2, des2 = surf.detectAndCompute(img2, None)
56
-
57
- if des1 is None or des2 is None:
58
- print("Erro: SURF não encontrou descritores suficientes.")
59
- return 0
60
-
61
- # Inicializa o matcher FlannBased
62
- index_params = dict(algorithm=0, trees=5) # FLANN_INDEX_KDTREE
63
- search_params = dict(checks=50)
64
- flann = cv2.FlannBasedMatcher(index_params, search_params)
65
- matches = flann.knnMatch(des1, des2, k=2)
66
-
67
- # Aplica o teste da razão de Lowe para filtrar correspondências boas
68
- good_matches = []
69
- for m, n in matches:
70
- if m.distance < 0.7 * n.distance:
71
- good_matches.append([m])
72
-
73
- return len(good_matches)
74
-
75
- except Exception as e:
76
- print(f"Erro ao calcular SURF: {e}")
77
- return 0
78
-
79
-
80
- def calcular_mse(img1, img2):
81
- """
82
- Calcula o Erro Quadrático Médio (MSE) entre duas imagens.
83
-
84
- Args:
85
- img1: A primeira imagem (array NumPy).
86
- img2: A segunda imagem (array NumPy).
87
-
88
- Returns:
89
- O valor do MSE ou -1 em caso de erro.
90
- """
91
- try:
92
- # Verifica se as imagens têm o mesmo tamanho
93
- if img1.shape != img2.shape:
94
- print("Erro: As imagens têm tamanhos diferentes. Redimensionando para calcular o MSE.")
95
- img1_resized = cv2.resize(img1, (img2.shape[1], img2.shape[0]))
96
- img1 = img1_resized
97
- # Converte as imagens para float64 para evitar overflow
98
- img1 = img1.astype(np.float64)
99
- img2 = img2.astype(np.float64)
100
- # Calcula a diferença entre as imagens
101
- diff = img1 - img2
102
- diff_squared = diff ** 2
103
- # Calcula o MSE
104
- mse = np.mean(diff_squared)
105
- return mse
106
- except Exception as e:
107
- print(f"Erro ao calcular MSE: {e}")
108
- return -1 # Retorna -1 para indicar um erro
109
-
110
-
111
-
112
-
113
  def orb_sim(img1, img2):
114
- """Calcula a similaridade entre duas imagens usando o algoritmo ORB."""
115
- try:
116
- # ORB
117
- orb = cv2.ORB_create()
118
- kp_a, desc_a = orb.detectAndCompute(img1, None)
119
- kp_b, desc_b = orb.detectAndCompute(img2, None)
120
-
121
- # Verifica se os descritores foram encontrados
122
- if desc_a is None or desc_b is None:
123
- print("Erro: ORB não encontrou descritores suficientes.")
124
- return 0
125
-
126
- # Brute-force matcher
127
- bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
128
- matches = bf.match(desc_a, desc_b)
129
- similar_regions = [i for i in matches if i.distance < 10]
130
- if len(matches) == 0:
131
- return 0
132
- return len(similar_regions) / len(matches)
133
- except Exception as e:
134
- print(f"Erro ao calcular similaridade ORB: {e}")
135
  return 0
136
-
137
 
138
  async def load_image(image_path: str):
139
  """Carrega uma imagem a partir de um caminho de arquivo ou URL."""
@@ -152,51 +42,31 @@ async def load_image(image_path: str):
152
  print(f"Erro ao carregar a imagem {image_path}: {e}")
153
  return None
154
 
 
155
 
 
156
 
157
  @app.post("/save")
158
  async def save(image_data: RequestModel):
159
- """
160
- Salva os dados da imagem, incluindo similaridade SIFT, SURF e MSE.
161
- """
162
  os.makedirs(BASE_DIR, exist_ok=True)
163
  filename = os.path.join(BASE_DIR, f"{image_data.originId}_{image_data.assetCode}.json")
 
164
  img1 = await load_image(image_data.originSource)
165
  img2 = await load_image(image_data.source)
166
 
167
  similarity_orb = None
168
- sift_matches = None
169
- surf_matches = None
170
- mse = None
171
-
172
  if img1 is not None and img2 is not None:
173
  similarity_orb = orb_sim(img1, img2)
174
- img1_gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
175
- img2_gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
176
- sift_matches = calcular_sift(img1_gray, img2_gray)
177
- surf_matches = calcular_surf(img1_gray, img2_gray)
178
- mse = calcular_mse(img1, img2)
179
  print(f"Similaridade ORB entre {image_data.originSource} e {image_data.source}: {similarity_orb}")
180
- print(f"Correspondências SIFT: {sift_matches}")
181
- print(f"Correspondências SURF: {surf_matches}")
182
- print(f"MSE: {mse}")
183
 
184
  data_to_save = image_data.dict()
185
  if similarity_orb is not None:
186
  data_to_save["similarityOrb"] = similarity_orb
187
- if sift_matches is not None:
188
- data_to_save["sift_matches"] = sift_matches
189
- if surf_matches is not None:
190
- data_to_save["surf_matches"] = surf_matches
191
- if mse is not None and mse >= 0: # Certifica-se que MSE é um valor válido
192
- data_to_save["mse"] = mse
193
 
194
  with open(filename, "w") as f:
195
  json.dump(data_to_save, f, indent=4)
196
  return True
197
 
198
-
199
-
200
  @app.get("/files")
201
  async def list_files():
202
  try:
@@ -206,20 +76,20 @@ async def list_files():
206
  if os.path.isfile(filepath):
207
  try:
208
  with open(filepath, "r") as f:
209
- file_content = f.read()
 
210
  try:
211
  file_content_json = json.loads(file_content)
212
  files_data.append({"filename": filename, "content": file_content_json})
213
  except json.JSONDecodeError:
214
- files_data.append({"filename": filename, "content": file_content})
215
  except (IOError, OSError) as e:
216
  raise HTTPException(status_code=500, detail=f"Erro ao ler o ficheiro {filename}: {e}")
 
217
  return JSONResponse({"files_data": files_data})
218
  except FileNotFoundError:
219
  raise HTTPException(status_code=404, detail="Diretório de dados não encontrado")
220
 
221
-
222
-
223
  @app.get("/files/similar")
224
  async def list_similar_files():
225
  try:
@@ -243,9 +113,6 @@ async def list_similar_files():
243
  except FileNotFoundError:
244
  raise HTTPException(status_code=404, detail="Diretório de dados não encontrado")
245
 
246
-
247
-
248
-
249
  @app.get("/files/find/{origin_id}")
250
  async def get_file_by_origin_id(origin_id: int):
251
  try:
@@ -265,4 +132,4 @@ async def get_file_by_origin_id(origin_id: int):
265
  raise HTTPException(status_code=500, detail=f"Erro ao ler o ficheiro {filename}: {e}")
266
  raise HTTPException(status_code=404, detail=f"Ficheiro com originId '{origin_id}' não encontrado")
267
  except FileNotFoundError:
268
- raise HTTPException(status_code=404, detail="Diretório de dados não encontrado")
 
1
+ from typing import List
2
+ from fastapi import FastAPI, HTTPException
3
+ from fastapi.responses import JSONResponse
4
+ from models import RequestModel
5
  import os
6
  import json
 
 
 
 
7
  import cv2
8
  import numpy as np
9
+ import httpx
10
 
11
+ BASE_DIR = "saved_data"
12
  app = FastAPI()
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  def orb_sim(img1, img2):
15
+ # ORB
16
+ orb = cv2.ORB_create()
17
+ kp_a, desc_a = orb.detectAndCompute(img1, None)
18
+ kp_b, desc_b = orb.detectAndCompute(img2, None)
19
+
20
+ # Brute-force matcher
21
+ bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
22
+ matches = bf.match(desc_a, desc_b)
23
+ similar_regions = [i for i in matches if i.distance < 10]
24
+ if len(matches) == 0:
 
 
 
 
 
 
 
 
 
 
 
25
  return 0
26
+ return len(similar_regions) / len(matches)
27
 
28
  async def load_image(image_path: str):
29
  """Carrega uma imagem a partir de um caminho de arquivo ou URL."""
 
42
  print(f"Erro ao carregar a imagem {image_path}: {e}")
43
  return None
44
 
45
+ app = FastAPI()
46
 
47
+ BASE_DIR = "/tmp/data"
48
 
49
  @app.post("/save")
50
  async def save(image_data: RequestModel):
 
 
 
51
  os.makedirs(BASE_DIR, exist_ok=True)
52
  filename = os.path.join(BASE_DIR, f"{image_data.originId}_{image_data.assetCode}.json")
53
+
54
  img1 = await load_image(image_data.originSource)
55
  img2 = await load_image(image_data.source)
56
 
57
  similarity_orb = None
 
 
 
 
58
  if img1 is not None and img2 is not None:
59
  similarity_orb = orb_sim(img1, img2)
 
 
 
 
 
60
  print(f"Similaridade ORB entre {image_data.originSource} e {image_data.source}: {similarity_orb}")
 
 
 
61
 
62
  data_to_save = image_data.dict()
63
  if similarity_orb is not None:
64
  data_to_save["similarityOrb"] = similarity_orb
 
 
 
 
 
 
65
 
66
  with open(filename, "w") as f:
67
  json.dump(data_to_save, f, indent=4)
68
  return True
69
 
 
 
70
  @app.get("/files")
71
  async def list_files():
72
  try:
 
76
  if os.path.isfile(filepath):
77
  try:
78
  with open(filepath, "r") as f:
79
+ file_content = f.read() # Lê o conteúdo do ficheiro
80
+ # Tenta decodificar o conteúdo como JSON, se possível
81
  try:
82
  file_content_json = json.loads(file_content)
83
  files_data.append({"filename": filename, "content": file_content_json})
84
  except json.JSONDecodeError:
85
+ files_data.append({"filename": filename, "content": file_content}) # Se não for JSON, retorna o texto
86
  except (IOError, OSError) as e:
87
  raise HTTPException(status_code=500, detail=f"Erro ao ler o ficheiro {filename}: {e}")
88
+
89
  return JSONResponse({"files_data": files_data})
90
  except FileNotFoundError:
91
  raise HTTPException(status_code=404, detail="Diretório de dados não encontrado")
92
 
 
 
93
  @app.get("/files/similar")
94
  async def list_similar_files():
95
  try:
 
113
  except FileNotFoundError:
114
  raise HTTPException(status_code=404, detail="Diretório de dados não encontrado")
115
 
 
 
 
116
  @app.get("/files/find/{origin_id}")
117
  async def get_file_by_origin_id(origin_id: int):
118
  try:
 
132
  raise HTTPException(status_code=500, detail=f"Erro ao ler o ficheiro {filename}: {e}")
133
  raise HTTPException(status_code=404, detail=f"Ficheiro com originId '{origin_id}' não encontrado")
134
  except FileNotFoundError:
135
+ raise HTTPException(status_code=404, detail="Diretório de dados não encontrado")