edit : 안경이미지 검색시 temp 이미지 사용 안함
This commit is contained in:
@@ -127,7 +127,12 @@ def get_clip_info(model, query_image_path, item_info, top_k=4):
|
|||||||
# item_info=item_info,
|
# item_info=item_info,
|
||||||
# index_type=model.value[1].index_type)
|
# index_type=model.value[1].index_type)
|
||||||
|
|
||||||
inference_times, result_img_paths, result_percents = vector_model.query_faiss(query_image_path, top_k=top_k)
|
if os.path.exists(query_image_path):
|
||||||
|
inference_times, result_img_paths, result_percents = vector_model.query_faiss(query_image_path, top_k=top_k)
|
||||||
|
elif query_image_path is None or query_image_path == "":
|
||||||
|
raise ValueError("query_image is None or empty.")
|
||||||
|
else:
|
||||||
|
inference_times, result_img_paths, result_percents = vector_model.query_faiss_image_data(query_image_path, top_k=top_k)
|
||||||
|
|
||||||
for i in range(len(result_percents)):
|
for i in range(len(result_percents)):
|
||||||
if float(result_percents[i]) < 0.0:
|
if float(result_percents[i]) < 0.0:
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS import feature_extraction_model
|
|||||||
# 사용할 이미지 임베딩 모델 클래스 추가
|
# 사용할 이미지 임베딩 모델 클래스 추가
|
||||||
from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.fem_openaiclipvit import FEOpenAIClipViT
|
from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.fem_openaiclipvit import FEOpenAIClipViT
|
||||||
from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.const import *
|
from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.const import *
|
||||||
|
from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.utils import get_base64_bytes
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Definition
|
Definition
|
||||||
@@ -219,6 +219,24 @@ class VectorSimilarity:
|
|||||||
feature_vectors = self.fem_model.image_embedding(image_data_np)
|
feature_vectors = self.fem_model.image_embedding(image_data_np)
|
||||||
return feature_vectors
|
return feature_vectors
|
||||||
|
|
||||||
|
def image_embedding_from_b64data(self, b64_data=None):
|
||||||
|
"""
|
||||||
|
이미지 데이터(base64)에서 특징 벡터 추출
|
||||||
|
:param image_data_np: 이미지 데이터(numpy)
|
||||||
|
:return: 특징 벡터 or None
|
||||||
|
"""
|
||||||
|
import io
|
||||||
|
feature_vectors = None
|
||||||
|
|
||||||
|
if b64_data is None:
|
||||||
|
log.error(f'invalid data[{b64_data}]')
|
||||||
|
return feature_vectors
|
||||||
|
|
||||||
|
image = Image.open(io.BytesIO(b64_data)).convert("RGB")
|
||||||
|
|
||||||
|
feature_vectors = self.fem_model.image_embedding(image)
|
||||||
|
return feature_vectors
|
||||||
|
|
||||||
def image_embedding_from_data(self, image_data_np=None):
|
def image_embedding_from_data(self, image_data_np=None):
|
||||||
"""
|
"""
|
||||||
이미지 데이터(numpy)에서 특징 벡터 추출
|
이미지 데이터(numpy)에서 특징 벡터 추출
|
||||||
@@ -372,6 +390,53 @@ class VectorSimilarity:
|
|||||||
|
|
||||||
return inference_times, result_img_paths, result_percents
|
return inference_times, result_img_paths, result_percents
|
||||||
|
|
||||||
|
def query_faiss_image_data(self, query_image_data=None, top_k=4):
|
||||||
|
|
||||||
|
if os.path.exists(self.txt_file_path):
|
||||||
|
with open(self.txt_file_path, 'r') as f:
|
||||||
|
image_paths = [line.strip() for line in f.readlines()]
|
||||||
|
else:
|
||||||
|
logging.error("Image path list TXT file not found.")
|
||||||
|
image_paths = []
|
||||||
|
|
||||||
|
b64_data = get_base64_bytes(query_image_data)
|
||||||
|
|
||||||
|
start_vector_time = datetime.now()
|
||||||
|
index = self.load_index(self.index_file_path)
|
||||||
|
query_vector = self.image_embedding_from_b64data(b64_data)
|
||||||
|
end_vector_time = datetime.now()
|
||||||
|
|
||||||
|
diff_vector_time = self.time_diff(start_vector_time,end_vector_time)
|
||||||
|
|
||||||
|
if self.index_type == INDEX_TYPE_COSINE:
|
||||||
|
faiss.normalize_L2(query_vector)
|
||||||
|
|
||||||
|
start_search_time = datetime.now()
|
||||||
|
distances, indices = index.search(query_vector, top_k)
|
||||||
|
end_search_time = datetime.now()
|
||||||
|
|
||||||
|
diff_search_time = self.time_diff(start_search_time,end_search_time)
|
||||||
|
diff_total_time = self.time_diff(start_vector_time,end_search_time)
|
||||||
|
inference_times = f"Total time - {diff_total_time}, vector_time - {diff_vector_time}, search_time - {diff_search_time}"
|
||||||
|
|
||||||
|
result_img_paths = []
|
||||||
|
result_percents = []
|
||||||
|
|
||||||
|
# 결과
|
||||||
|
# for i in range(top_k):
|
||||||
|
# print(f"{i + 1}: {image_paths[indices[0][i]]}, Distance: {distances[0][i]}")
|
||||||
|
for idx, dist in zip(indices[0], distances[0]):
|
||||||
|
log.debug(f"{idx} (거리: {dist:.4f})")
|
||||||
|
|
||||||
|
result_img_paths.append(image_paths[idx])
|
||||||
|
|
||||||
|
if self.index_type == INDEX_TYPE_COSINE:
|
||||||
|
result_percents.append(f"{dist*100:.2f}")
|
||||||
|
else:
|
||||||
|
result_percents.append(f"{((1 - dist)*100):.2f}")
|
||||||
|
|
||||||
|
return inference_times, result_img_paths, result_percents
|
||||||
|
|
||||||
# def test():
|
# def test():
|
||||||
# """
|
# """
|
||||||
# module test function
|
# module test function
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
import base64
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.const import *
|
from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.const import *
|
||||||
@@ -43,5 +44,29 @@ def file_name_to_parts(file_path):
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def get_base64_bytes(data: str) -> bytes:
|
||||||
|
"""
|
||||||
|
문자열을 검사하여 유효한 Base64라면 디코딩된 bytes 데이터를 반환하고,
|
||||||
|
그렇지 않으면 ValueError 예외를 발생시킵니다.
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 1. 입력 문자열 전처리 (공백 제거 등)
|
||||||
|
stripped_data = data.strip()
|
||||||
|
|
||||||
|
# 2. bytes로 인코딩 (b64decode는 bytes-like object를 필요로 함)
|
||||||
|
encoded_input = stripped_data.encode('ascii')
|
||||||
|
|
||||||
|
# 3. Base64 디코딩 수행 (validate=True로 엄격한 검사)
|
||||||
|
# 성공 시 b'...' 형태의 바이트 데이터가 생성됨
|
||||||
|
decoded_bytes = base64.b64decode(encoded_input, validate=True)
|
||||||
|
|
||||||
|
return decoded_bytes
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
# Base64 형식이 아니거나 패딩 오류 등 발생 시
|
||||||
|
raise ValueError(f"유효한 Base64 데이터가 아닙니다. 변환 불가: {e}")
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print(file_name_to_parts(os.path.join(FAISS_VECTOR_PATH,"Glass_001",ImageDepths.parts,"Glass_001_Temple_L.png")))
|
print(file_name_to_parts(os.path.join(FAISS_VECTOR_PATH,"Glass_001",ImageDepths.parts,"Glass_001_Temple_L.png")))
|
||||||
@@ -507,9 +507,12 @@ async def vactor_vit_input_glasses_img_data(request: Request, request_body_info:
|
|||||||
raise Exception(f"indexType is invalid (current value = {request_body_info.indexType})")
|
raise Exception(f"indexType is invalid (current value = {request_body_info.indexType})")
|
||||||
|
|
||||||
query_image_data = request_body_info.inputImage
|
query_image_data = request_body_info.inputImage
|
||||||
query_image_path = os.path.join(TEMP_FOLDER, f'input_{D.date_file_name()}_query.png')
|
|
||||||
os.makedirs(TEMP_FOLDER, exist_ok=True)
|
# query_image_path = os.path.join(TEMP_FOLDER, f'input_{D.date_file_name()}_query.png')
|
||||||
save_base64_as_image_file(request_body_info.inputImage ,query_image_path)
|
# os.makedirs(TEMP_FOLDER, exist_ok=True)
|
||||||
|
# save_base64_as_image_file(request_body_info.inputImage ,query_image_path)
|
||||||
|
|
||||||
|
query_image_path = query_image_data
|
||||||
|
|
||||||
vector_request_data = {'query_image_path' : query_image_path,
|
vector_request_data = {'query_image_path' : query_image_path,
|
||||||
'index_type' : request_body_info.indexType,
|
'index_type' : request_body_info.indexType,
|
||||||
|
|||||||
@@ -118,5 +118,3 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
for item_key, item_value in pure_data_dict.items():
|
for item_key, item_value in pure_data_dict.items():
|
||||||
make_vector_files(item_info=item_value, index_type=VM.VitIndexType.l2, model_type=VM.VitModelType.b32)
|
make_vector_files(item_info=item_value, index_type=VM.VitIndexType.l2, model_type=VM.VitModelType.b32)
|
||||||
|
|
||||||
# time.sleep(5) # huggingface api 요청 제한 회피 위해 대기 TODO(jwkim) huggingface 로그인은 한번만 진행하게 변경
|
|
||||||
@@ -84,8 +84,8 @@ async def vactor_vit(request: Request, request_body_info: M.VectorSearchVitReq):
|
|||||||
"""
|
"""
|
||||||
response = M.VectorSearchVitRes()
|
response = M.VectorSearchVitRes()
|
||||||
try:
|
try:
|
||||||
if not os.path.exists(request_body_info.query_image_path):
|
# if not os.path.exists(request_body_info.query_image_path):
|
||||||
raise FileNotFoundError(f"File {request_body_info.query_image_path} does not exist.")
|
# raise FileNotFoundError(f"File {request_body_info.query_image_path} does not exist.")
|
||||||
|
|
||||||
model = get_models(index_type=request_body_info.index_type, model_type=request_body_info.model_type)
|
model = get_models(index_type=request_body_info.index_type, model_type=request_body_info.model_type)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user