Compare commits

...

8 Commits

23 changed files with 830 additions and 398 deletions

4
.gitignore vendored
View File

@@ -145,8 +145,6 @@ log
*output *output
*temp *temp
datas/eyewear_all/* datas/*
datas/clip*
datas/openai*
*result *result

View File

@@ -1,4 +1,4 @@
# FM_TEST_REST_SERVER # GLASSES_AI_SERVER
RESTful API Server RESTful API Server

View File

@@ -26,6 +26,7 @@ class Config:
self.sftp_port = 22 self.sftp_port = 22
self.sftp_id = "fermat" self.sftp_id = "fermat"
self.sftp_pw = "fermat3514" self.sftp_pw = "fermat3514"
self.db_pw = "1234"
if not os.path.exists(self.remote_folder): if not os.path.exists(self.remote_folder):
os.makedirs(self.remote_folder) os.makedirs(self.remote_folder)
@@ -34,6 +35,8 @@ class Config:
self.config = 'release' self.config = 'release'
self.local_folder = "./result" # 결과물 저장 폴더 self.local_folder = "./result" # 결과물 저장 폴더
self.db_pw = "Fermat3514!"
if not os.path.exists(self.local_folder): if not os.path.exists(self.local_folder):
os.makedirs(self.local_folder) os.makedirs(self.local_folder)

View File

22
custom_apps/FEATURE_VECTOR_SIMILARITY_FAISS/const.py Executable file → Normal file
View File

@@ -19,10 +19,26 @@ ViTL14_336 = "clip-vit-large-patch14-336"
#download/save path #download/save path
PRETRAINED_MODEL_PATH = "./datas" PRETRAINED_MODEL_PATH = "./datas"
FAISS_VECTOR_PATH = "./datas" FAISS_VECTOR_PATH = "./datas"
VECTOR_IMG_LIST_PATH = "./datas" IMG_LIST_PATH = "../Eyewear_data"
INDEX_IMAGES_PATH = "./datas/eyewear_all"
# INDEX_IMAGES_PATH = "./datas/eyewear_all"
class VectorSearchItem:
glass = "glass"
tips = "Tips"
temple = "Temple"
rim = "Rim"
rim2 = "Rim2"
noesPad = "Nose pad"
noseArm = "Nose arm"
lens = "Lens"
endPiece = "End piece"
hinges = "Hinges"
screw = "Screw"
bridge = "Bridge"
class ImageDepths:
parts = "Parts"
thumnails = "Thumbnails"
# report image consts # report image consts
class ReportInfoConst: class ReportInfoConst:

View File

@@ -100,22 +100,32 @@ def save_report_image(report_info, report_image_path):
table_setting(report_info, report_image_path) table_setting(report_info, report_image_path)
def get_clip_info(model, query_image_path, top_k=4): def get_clip_info(model, query_image_path, item_info, top_k=4):
""" """
이미지 유사도 검색 이미지 유사도 검색
""" """
index_file_path = os.path.join(VECTOR_IMG_LIST_PATH,f'{model.name}_{os.path.basename(model.value[1].trained_model)}_{model.value[1].index_type}_{DEFAULT_INDEX_NAME_SUFFIX}') index_file_path = os.path.join(FAISS_VECTOR_PATH,f'{model.name}_{os.path.basename(model.value[1].trained_model)}_{model.value[1].index_type}_{item_info}_{DEFAULT_INDEX_NAME_SUFFIX}')
txt_file_path = os.path.join(VECTOR_IMG_LIST_PATH,f'{model.name}_{os.path.basename(model.value[1].trained_model)}_{model.value[1].index_type}.txt') txt_file_path = os.path.join(FAISS_VECTOR_PATH,f'{model.name}_{os.path.basename(model.value[1].trained_model)}_{model.value[1].index_type}_{item_info}.txt')
if not os.path.exists(index_file_path) or not os.path.exists(txt_file_path):
raise FileNotFoundError(f"Index file {index_file_path} or txt file {txt_file_path} does not exist.")
vector_model = VectorSimilarity(model_info=model, vector_model = VectorSimilarity(model_info=model,
index_file_path=index_file_path, index_file_path=index_file_path,
txt_file_path=txt_file_path) txt_file_path=txt_file_path)
# image_lists = []
# with open(txt_file_path, 'r') as f:
# image_lists = [line.strip() for line in f.readlines()]
# vector_model.create_feature_extraction_model(FEMUsageInfo.openaiclipvit) # vector_model.create_feature_extraction_model(FEMUsageInfo.openaiclipvit)
vector_model.save_index_from_files(images_path=INDEX_IMAGES_PATH, # vector_model.save_index_from_files(images_path_lists=image_lists,
save_index_dir=FAISS_VECTOR_PATH, # save_index_dir=FAISS_VECTOR_PATH,
save_txt_dir=VECTOR_IMG_LIST_PATH, # save_txt_dir=VECTOR_IMG_LIST_PATH,
index_type=model.value[1].index_type) # item_info=item_info,
# 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) inference_times, result_img_paths, result_percents = vector_model.query_faiss(query_image_path, top_k=top_k)
@@ -131,5 +141,56 @@ def get_clip_info(model, query_image_path, top_k=4):
) )
return report_info return report_info
def find_glass_folder_images(root_folder):
"""
glass(thumnails) 폴더 내의 모든 이미지 파일 경로를 재귀적으로 탐색하여 리스트로 반환합니다.
Args:
root_folder (str): 탐색을 시작할 최상위 폴더
Returns:
list: 발견된 이미지 파일 전체 경로의 리스트.
"""
image_paths = []
for dirpath, dirnames, filenames in os.walk(root_folder):
if os.path.basename(dirpath) == ImageDepths.thumnails:
for filename in filenames:
if filename.lower().endswith(('.png', '.jpg', '.jpeg')):
# 파일의 전체 경로를 생성하여 리스트에 추가
full_path = os.path.join(dirpath, filename)
image_paths.append(full_path)
return image_paths
def find_parts_folder_images(root_folder, parts):
"""
parts 폴더 내의 해당하는 파츠 이미지 파일 경로를 재귀적으로 탐색하여 리스트로 반환합니다.
Args:
root_folder (str): 탐색을 시작할 최상위 폴더
Returns:
list: 발견된 이미지 파일 경로의 리스트.
"""
image_paths = []
for dirpath, dirnames, filenames in os.walk(root_folder):
if os.path.basename(dirpath) == ImageDepths.parts:
for filename in filenames:
if filename.lower().endswith(('.png', '.jpg', '.jpeg')) and parts in filename:
# 파일의 전체 경로를 생성하여 리스트에 추가
full_path = os.path.join(dirpath, filename)
image_paths.append(full_path)
return image_paths

View File

@@ -234,73 +234,67 @@ 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 save_index_from_files(self, images_path=None, save_index_dir=None, save_txt_dir=None, index_type=INDEX_TYPE_L2): def save_index_from_files(self, images_path_lists=None, save_index_dir=None, save_txt_dir=None, item_info=None, index_type=INDEX_TYPE_L2):
""" """
인덱스 정보 저장 인덱스 정보 저장
:param images_path: 이미지 파일 경로 :param images_path: 이미지 파일 경로
:param save_index_dir: 인덱스 저장 디렉토리 :param save_index_dir: 인덱스 저장 디렉토리
:param save_txt_dir: 이미지 경로 저장 디렉토리 :param save_txt_dir: 이미지 경로 저장 디렉토리
:param item_info: 아이템 정보
:param index_type: 인덱스 타입 (L2, Cosine) :param index_type: 인덱스 타입 (L2, Cosine)
:return: 이미지 임베딩 차원 정보 :return: 이미지 임베딩 차원 정보
""" """
assert self.fem_model is not None, 'invalid fem_model' assert self.fem_model is not None, 'invalid fem_model'
assert images_path is not None, 'images_path is required' assert images_path_lists is not None, 'images_path is required'
if not os.path.exists(images_path):
log.error(f'image_path={images_path} does not exist')
image_folder = images_path
result = None result = None
# 모든 이미지 임베딩 모으기 image_paths = images_path_lists
if os.path.exists(image_folder): image_vectors = np.vstack([self.image_embedding_from_file(image_file) for image_file in image_paths])
image_paths = [os.path.join(image_folder, image_file) for image_file in os.listdir(image_folder)] log.debug(f'image_vectors.shape={image_vectors.shape}')
image_vectors = np.vstack([self.image_embedding_from_file(image_file) for image_file in image_paths]) result = image_vectors.shape
log.debug(f'image_vectors.shape={image_vectors.shape}')
result = image_vectors.shape
# 인덱스 생성 (L2) # 인덱스 생성 (L2)
dimension = image_vectors.shape[1] dimension = image_vectors.shape[1]
if index_type == INDEX_TYPE_L2: if index_type == INDEX_TYPE_L2:
index = faiss.IndexFlatL2(dimension) # L2 index = faiss.IndexFlatL2(dimension) # L2
elif index_type == INDEX_TYPE_COSINE: elif index_type == INDEX_TYPE_COSINE:
index = faiss.IndexFlatIP(dimension) # cosine index = faiss.IndexFlatIP(dimension) # cosine
faiss.normalize_L2(image_vectors) faiss.normalize_L2(image_vectors)
else:
raise Exception(f'Invalid index_type={index_type}')
index.add(image_vectors)
# 인덱스 저장
if save_index_dir is None:
save_index_path = os.path.join(FILE_BASE_PATH,f'{self.fem_model_name}_{os.path.basename(self.fem_model_args.trained_model)}_{index_type}_{DEFAULT_SAVE_INDEX_SUFFIX}')
self.index_file_path = save_index_path
else:
save_index_path = os.path.join(save_index_dir,f'{self.fem_model_name}_{os.path.basename(self.fem_model_args.trained_model)}_{index_type}_{DEFAULT_SAVE_INDEX_SUFFIX}')
os.makedirs(save_index_dir, exist_ok=True)
# 이미지 경로 파일 저장
if save_txt_dir is None:
save_txt_path = os.path.join(FILE_BASE_PATH, f'{self.fem_model_name}_{os.path.basename(self.fem_model_args.trained_model)}_{index_type}.txt')
self.txt_file_path = save_txt_path
else:
save_txt_path = os.path.join(save_txt_dir, f'{self.fem_model_name}_{os.path.basename(self.fem_model_args.trained_model)}_{index_type}.txt')
os.makedirs(save_txt_dir, exist_ok=True)
if not os.path.exists(save_txt_path):
faiss.write_index(index, save_index_path)
log.debug(f'save_index_path={save_index_path}')
if not os.path.exists(save_txt_path):
# 이미지 경로 저장
with open(save_txt_path, 'w') as f:
for path in image_paths:
f.write(f"{path}\n")
log.debug(f'save_txt_path={save_txt_path}')
else: else:
log.error(f'Image folder {image_folder} does not exist') raise Exception(f'Invalid index_type={index_type}')
index.add(image_vectors)
# 인덱스 저장
if save_index_dir is None:
save_index_path = os.path.join(FILE_BASE_PATH,f'{self.fem_model_name}_{os.path.basename(self.fem_model_args.trained_model)}_{index_type}_{item_info}_{DEFAULT_SAVE_INDEX_SUFFIX}')
self.index_file_path = save_index_path
else:
save_index_path = os.path.join(save_index_dir,f'{self.fem_model_name}_{os.path.basename(self.fem_model_args.trained_model)}_{index_type}_{item_info}_{DEFAULT_SAVE_INDEX_SUFFIX}')
os.makedirs(save_index_dir, exist_ok=True)
# # 이미지 경로 파일 저장
# if save_txt_dir is None:
# save_txt_path = os.path.join(FILE_BASE_PATH, f'{self.fem_model_name}_{os.path.basename(self.fem_model_args.trained_model)}_{index_type}.txt')
# self.txt_file_path = save_txt_path
# else:
# save_txt_path = os.path.join(save_txt_dir, f'{self.fem_model_name}_{os.path.basename(self.fem_model_args.trained_model)}_{index_type}.txt')
# os.makedirs(save_txt_dir, exist_ok=True)
if not os.path.exists(save_index_path):
faiss.write_index(index, save_index_path)
log.debug(f'save_index_path={save_index_path}')
# if not os.path.exists(save_txt_path):
# # 이미지 경로 저장
# with open(save_txt_path, 'w') as f:
# for path in image_paths:
# f.write(f"{path}\n")
# log.debug(f'save_txt_path={save_txt_path}')
return result return result
def set_index_path(self, index_path): def set_index_path(self, index_path):
@@ -378,33 +372,33 @@ class VectorSimilarity:
return inference_times, result_img_paths, result_percents return inference_times, result_img_paths, result_percents
def test(): # def test():
""" # """
module test function # module test function
""" # """
log.info('\nModule: faiss_similarity_search.py') # log.info('\nModule: faiss_similarity_search.py')
# index_file_path = f'{FILE_BASE_PATH}openaiclipvit_clip-vit-base-patch32_index.faiss' # # index_file_path = f'{FILE_BASE_PATH}openaiclipvit_clip-vit-base-patch32_index.faiss'
model = FEMUsageInfo.openaiclip_vit_l14_cos # model = FEMUsageInfo.openaiclip_vit_l14_cos
index_file_path = os.path.join(VECTOR_IMG_LIST_PATH,f'{model.name}_{os.path.basename(model.value[1].trained_model)}_{model.value[1].index_type}_{DEFAULT_INDEX_NAME_SUFFIX}') # index_file_path = os.path.join(VECTOR_IMG_LIST_PATH,f'{model.name}_{os.path.basename(model.value[1].trained_model)}_{model.value[1].index_type}_{DEFAULT_INDEX_NAME_SUFFIX}')
cm = VectorSimilarity(model_info=model, # cm = VectorSimilarity(model_info=model,
index_file_path=index_file_path, # index_file_path=index_file_path,
txt_file_path=os.path.join(VECTOR_IMG_LIST_PATH,f'{model.name}_{os.path.basename(model.value[1].trained_model)}_{model.value[1].index_type}.txt')) # txt_file_path=os.path.join(VECTOR_IMG_LIST_PATH,f'{model.name}_{os.path.basename(model.value[1].trained_model)}_{model.value[1].index_type}.txt'))
# cm.create_feature_extraction_model(FEMUsageInfo.openaiclipvit) # # cm.create_feature_extraction_model(FEMUsageInfo.openaiclipvit)
cm.save_index_from_files(images_path=INDEX_IMAGES_PATH, # cm.save_index_from_files(images_path_lists=INDEX_IMAGES_PATH,
save_index_dir=FAISS_VECTOR_PATH, # save_index_dir=FAISS_VECTOR_PATH,
save_txt_dir=VECTOR_IMG_LIST_PATH, # save_txt_dir=VECTOR_IMG_LIST_PATH,
index_type=model.value[1].index_type) # index_type=model.value[1].index_type)
cm.query_faiss(os.path.join(INDEX_IMAGES_PATH,"img1.png")) # cm.query_faiss(os.path.join(INDEX_IMAGES_PATH,"img1.png"))
if __name__ == '__main__': if __name__ == '__main__':
""" """
test module test module
""" """
test() # test()

View File

View File

View File

@@ -0,0 +1,39 @@
import os
from pathlib import Path
from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.const import *
def search_glass_parts(image_path_list):
result = []
for image_path in image_path_list:
parts_path = Path(os.path.join(os.path.dirname(os.path.dirname(image_path)),ImageDepths.parts))
parts_files_generator = parts_path.rglob('*.png')
parts_list = []
# parts_list = [str(p.resolve()) for p in parts_files_generator] # 풀경로
for p in parts_files_generator:
# name,ext = os.path.splitext(p.name)
parts_list.append(p.name)
result.append(parts_list)
return result
def file_name_to_parts(file_path):
"""
파일경로로 파츠이름 파싱
:param file_path: 파일경로
:return: 파츠이름
"""
filename, ext = os.path.splitext(os.path.basename(file_path))
name_list = filename.split('_')
result = name_list[2:][0]
return result
if __name__ == '__main__':
print(file_name_to_parts(os.path.join(FAISS_VECTOR_PATH,"Glass_001",ImageDepths.parts,"Glass_001_Temple_L.png")))

View File

@@ -14,11 +14,11 @@ def gemini_image(prompt, folder=None):
from custom_logger.main_log import main_logger as LOG from custom_logger.main_log import main_logger as LOG
image_path = '' image_path = ''
client = genai.Client(api_key="AIzaSyB7tu67y9gOkJkpQtvI5OAYSzUzwv9qwnE") client = genai.Client(api_key="AIzaSyCSw4pcPDYdAnjzBB7J9ZKXtRJJvunjWtA") # a2tec key
for i in range(3): for i in range(3):
response = client.models.generate_content( response = client.models.generate_content(
model="gemini-2.0-flash-preview-image-generation", model="gemini-2.5-flash-image",
contents=prompt, contents=prompt,
config=types.GenerateContentConfig( config=types.GenerateContentConfig(
response_modalities=['TEXT', 'IMAGE'] response_modalities=['TEXT', 'IMAGE']

View File

@@ -2,7 +2,7 @@
""" """
@file : custom_log.py @file : custom_log.py
@author: hsj100 @author: hsj100
@license: DAOOLDNS @license: A2TEC
@brief: @brief:
@section Modify History @section Modify History
- 2024-05-08 오후 2:33 hsj100 base - 2024-05-08 오후 2:33 hsj100 base

View File

@@ -8,15 +8,16 @@
- 2022-01-14/hsj100@a2tec.co.kr : refactoring - 2022-01-14/hsj100@a2tec.co.kr : refactoring
@brief: consts @brief: consts
""" """
from config import rest_config
# SUPPORT PROJECT # SUPPORT PROJECT
SUPPORT_PROJECT_BASIC = 'PROJECT_BASIC' SUPPORT_PROJECT_BASIC = 'PROJECT_BASIC'
PROJECT_NAME = 'FERMAT-TEST' PROJECT_NAME = 'K_EYEWEAR'
SW_TITLE= f'{PROJECT_NAME} - REST API' SW_TITLE= f'{PROJECT_NAME} - REST API'
SW_VERSION = '0.1.0' SW_VERSION = '0.2.0'
SW_DESCRIPTION = f''' SW_DESCRIPTION = f'''
### FERMAT-TEST REST API ### K_EYEWEAR REST API
## API 이용법 ## API 이용법
- 개별 API 설명과 Request/Response schema 참조 - 개별 API 설명과 Request/Response schema 참조
@@ -87,7 +88,7 @@ NUM_RETRY_UUID_GEN = 3
DB_ADDRESS = "localhost" DB_ADDRESS = "localhost"
DB_PORT = 53306 DB_PORT = 53306
DB_USER_ID = 'root' DB_USER_ID = 'root'
DB_USER_PW = '1234' DB_USER_PW = rest_config.db_pw
DB_NAME = 'FM_TEST' DB_NAME = 'FM_TEST'
DB_CHARSET = 'utf8mb4' DB_CHARSET = 'utf8mb4'

View File

@@ -30,7 +30,7 @@ from main_rest.app.common.consts import (
DEFAULT_USER_ACCOUNT_PW DEFAULT_USER_ACCOUNT_PW
) )
from main_rest.app.utils.date_utils import D from main_rest.app.utils.date_utils import D
from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.const import VectorSearchItem
class SWInfo(BaseModel): class SWInfo(BaseModel):
""" """
@@ -581,12 +581,13 @@ class VitModelType:
b16 = "b16" b16 = "b16"
l14 = "l14" l14 = "l14"
l14_336 = "l14_336" l14_336 = "l14_336"
class ImageGenerateReq(BaseModel): class ImageGenerateReq(BaseModel):
""" """
### [Request] image generate request ### [Request] image generate request
""" """
prefix : Optional[str] = Field(default="하얀색 배경", description="접두사", example="하얀색 배경")
prompt : str = Field(description='프롬프트', example='검은색 안경') prompt : str = Field(description='프롬프트', example='검은색 안경')
class BingCookieSetReq(BaseModel): class BingCookieSetReq(BaseModel):
@@ -610,21 +611,29 @@ class VectorImageSearchVitReq(BaseModel):
### [Request] vector image search vit ### [Request] vector image search vit
""" """
prompt : str = Field(description='프롬프트', example='검은색 안경') prompt : str = Field(description='프롬프트', example='검은색 안경')
modelType : str = Field(VitModelType.l14, description='pretrained model 타입', example=VitModelType.l14) modelType : str = Field(VitModelType.b32, description='pretrained model 타입', example=VitModelType.b32)
indexType : str = Field(VitIndexType.l2, description='인덱스 타입', example=VitIndexType.l2) indexType : str = Field(VitIndexType.l2, description='인덱스 타입', example=VitIndexType.l2)
searchNum : int = Field(4, description='검색결과 이미지 갯수', example=4) searchNum : int = Field(4, description='검색결과 이미지 갯수', example=4)
class VectorImageSearchVitInputImgReq(BaseModel): class VectorGlassesImageSearchVitInputImgReq(BaseModel):
""" """
### [Request] vector image search vit - input image ### [Request] vector image search vit - input image
""" """
inputImage : str = Field(description='base64 이미지', example='') inputImage : str = Field(description='base64 이미지', example='')
modelType : str = Field(VitModelType.l14, description='pretrained model 타입', example=VitModelType.l14) modelType : str = Field(VitModelType.b32, description='pretrained model 타입', example=VitModelType.b32)
indexType : str = Field(VitIndexType.l2, description='인덱스 타입', example=VitIndexType.l2) indexType : str = Field(VitIndexType.l2, description='인덱스 타입', example=VitIndexType.l2)
searchNum : int = Field(4, description='검색결과 이미지 갯수', example=4) searchNum : int = Field(4, description='검색결과 이미지 갯수', example=4)
class VectorPartsImageSearchVitInputImgReq(VectorGlassesImageSearchVitInputImgReq):
"""
### [Request] vector image search vit data - input image
"""
inputImage : str = Field(description='파츠이미지 이름', example='')
class VectorImageSearchVitDataReq(VectorImageSearchVitReq): class VectorImageSearchVitDataReq(VectorImageSearchVitReq):
""" """
### [Request] vector image search vit data ### [Request] vector image search vit data
@@ -641,10 +650,17 @@ class VectorImageSearchVitReportReq(BaseModel):
indexType : str = Field(VitIndexType.l2, description='인덱스 타입', example=VitIndexType.l2) indexType : str = Field(VitIndexType.l2, description='인덱스 타입', example=VitIndexType.l2)
class VectorImageResult(BaseModel): class VectorGlassesImageResult(BaseModel):
image : str = Field("", description='이미지 데이터', example='') image : str = Field("", description='이미지 데이터', example='')
percents: float = Field(0.0, description='percents 값', example='') percents: float = Field(0.0, description='percents 값', example='')
imageInfo : str = Field("", description='원본이미지 이름', example='')
parts: list = Field([], description='안경 파츠 정보', example=[])
class VectorPartsImageResult(BaseModel):
image : str | None = Field("", description='이미지 데이터', example='')
percents: float = Field(0.0, description='percents 값', example='')
imageInfo : str = Field("", description='원본이미지 이름', example='')
#=============================================================================== #===============================================================================
#=============================================================================== #===============================================================================
#=============================================================================== #===============================================================================
@@ -714,12 +730,12 @@ class BingCookieSetRes(ResponseBase):
return BingCookieSetRes return BingCookieSetRes
class VectorImageSerachDataRes(ResponseBase): class VectorGlassesImageSerachDataRes(ResponseBase):
""" """
### vector image data response ### vector image data response
""" """
queryImage : str = Field("", description='쿼리 이미지', example="") queryImage : str = Field("", description='쿼리 이미지', example="")
vectorResult : List[VectorImageResult] = Field([], description='벡터 검색 결과', example=[]) vectorResult : List[VectorGlassesImageResult] = Field([], description='벡터 검색 결과', example=[])
@staticmethod @staticmethod
def set_error(error,vector_result=[],query_img=""): def set_error(error,vector_result=[],query_img=""):
@@ -737,4 +753,8 @@ class VectorImageSerachDataRes(ResponseBase):
ImageGenerateRes.vectorResult = vector_result ImageGenerateRes.vectorResult = vector_result
ImageGenerateRes.queryImage = query_img ImageGenerateRes.queryImage = query_img
return ImageGenerateRes return ImageGenerateRes
class VectorPartsImageSerachDataRes(VectorGlassesImageSerachDataRes):
vectorResult : List[VectorPartsImageResult] = Field([], description='벡터 검색 결과', example=[])

View File

@@ -135,3 +135,75 @@ async def test(request: Request):
return a return a
# @router.post("/vectorImageSearch/vit/imageGenerate/imagen/report", summary="벡터 이미지 검색(clip-vit) - imagen, report 생성", response_model=M.ResponseBase)
# async def vactor_vit_report(request: Request, request_body_info: M.VectorImageSearchVitReportReq):
# """
# ## 벡터 이미지 검색(clip-vit) - imagen, report 생성
# > imagen AI를 이용하여 이미지 생성 후 vector 검색 그후 종합결과 이미지 생성
# ### Requriements
# > - googlecli 설치(https://cloud.google.com/sdk/docs/install?hl=ko#linux)
# ### options
# > - modelType -> b32,b16,l14,l14_336
# > - indexType -> l2,cos
# """
# response = M.ResponseBase()
# try:
# if request_body_info.modelType not in [M.VitModelType.b32, M.VitModelType.b16, M.VitModelType.l14, M.VitModelType.l14_336]:
# raise Exception(f"modelType is invalid (current value = {request_body_info.modelType})")
# if request_body_info.indexType not in [M.VitIndexType.cos, M.VitIndexType.l2]:
# raise Exception(f"indexType is invalid (current value = {request_body_info.indexType})")
# # query_image_path = imagen_generate_temp_image_path(image_prompt=request_body_info.prompt) #imagen
# query_image_path = gemini_image(request_body_info.prompt) #gemini
# report_image_path = f"{os.path.splitext(query_image_path)[0]}_report.png"
# vactor_request_data = {'query_image_path' : query_image_path,
# 'index_type' : request_body_info.indexType,
# 'model_type' : request_body_info.modelType,
# 'report_path' : report_image_path}
# vactor_response = requests.post('http://localhost:51002/api/services/faiss/vector/search/vit/report', data=json.dumps(vactor_request_data))
# if vactor_response.status_code != 200:
# raise Exception(f"response error: {json.loads(vactor_response.text)['error']}")
# if json.loads(vactor_response.text)["error"] != None:
# raise Exception(f"vector error: {json.loads(vactor_response.text)['error']}")
# if rest_config.config != 'release':
# # remote 폴더에 이미지 저장
# sftp_client.remote_copy_data(local_path=report_image_path,
# remote_path=os.path.join(rest_config.remote_folder, f"imagen_report_vit_{request_body_info.prompt}_{D.date_file_name()}.png"))
# else:
# shutil.copy(report_image_path, os.path.join(rest_config.local_folder, f"imagen_report_vit_{request_body_info.prompt}_{D.date_file_name()}.png"))
# # Clean up temporary files
# if 'query_image_path' in locals():
# if os.path.exists(query_image_path):
# os.remove(query_image_path)
# del query_image_path
# if 'report_image_path' in locals():
# if os.path.exists(report_image_path):
# os.remove(report_image_path)
# del report_image_path
# return response.set_message()
# except Exception as e:
# LOG.error(traceback.format_exc())
# # Clean up temporary files
# if 'query_image_path' in locals():
# if os.path.exists(query_image_path):
# os.remove(query_image_path)
# del query_image_path
# if 'report_image_path' in locals():
# if os.path.exists(report_image_path):
# os.remove(report_image_path)
# del report_image_path
# return response.set_error(error=e)

View File

@@ -30,6 +30,8 @@ from utils.custom_sftp import sftp_client
from config import rest_config from config import rest_config
from const import TEMP_FOLDER from const import TEMP_FOLDER
from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.const import *
router = APIRouter(prefix="/services") router = APIRouter(prefix="/services")
# @router.post("/bing/cookie/set", summary="bing 관련 쿠키 set", response_model=M.BingCookieSetRes) # @router.post("/bing/cookie/set", summary="bing 관련 쿠키 set", response_model=M.BingCookieSetRes)
@@ -123,88 +125,88 @@ router = APIRouter(prefix="/services")
# LOG.error(traceback.format_exc()) # LOG.error(traceback.format_exc())
# return response.set_error(e) # return response.set_error(e)
@router.post("/imageGenerate/imagen", summary="이미지 생성(AI) - imagen", response_model=M.ResponseBase) # @router.post("/imageGenerate/imagen", summary="이미지 생성(AI) - imagen", response_model=M.ResponseBase)
async def imagen(request: Request, request_body_info: M.ImageGenerateReq): # async def imagen(request: Request, request_body_info: M.ImageGenerateReq):
""" # """
## 이미지 생성(AI) - imagen # ## 이미지 생성(AI) - imagen
> imagen AI를 이용하여 이미지 생성 # > imagen AI를 이용하여 이미지 생성
""" # """
# imagen 사용중단 gemini로 변경 # # imagen 사용중단 gemini로 변경
response = M.ResponseBase() # response = M.ResponseBase()
try: # try:
# NOTE(JWKIM) : imagen 사용 중단 # # NOTE(JWKIM) : imagen 사용 중단
# img_length = imagen_generate_image(prompt=request_body_info.prompt, # # img_length = imagen_generate_image(prompt=request_body_info.prompt,
# download_count=request_body_info.downloadCount # # download_count=request_body_info.downloadCount
# ) # # )
temp_image_path = gemini_image(request_body_info.prompt) # temp_image_path = gemini_image(request_body_info.prompt)
if rest_config.config != 'release': # if rest_config.config != 'release':
_remote_folder = os.path.join(rest_config.remote_folder,"imagen") # _remote_folder = os.path.join(rest_config.remote_folder,"imagen")
# remote save # # remote save
sftp_client.remote_copy_data( # sftp_client.remote_copy_data(
temp_image_path, # temp_image_path,
os.path.join(_remote_folder,f"imagen_{request_body_info.prompt}_{1}_{D.date_file_name()}.png")) # os.path.join(_remote_folder,f"imagen_{request_body_info.prompt}_{1}_{D.date_file_name()}.png"))
else: # else:
_local_forder = os.path.join(rest_config.local_folder,"image_generate","imagen") # _local_forder = os.path.join(rest_config.local_folder,"image_generate","imagen")
os.makedirs(_local_forder,exist_ok=True) # os.makedirs(_local_forder,exist_ok=True)
shutil.copy(temp_image_path, os.path.join(_local_forder,f"imagen_{request_body_info.prompt}_{1}_{D.date_file_name()}.png")) # shutil.copy(temp_image_path, os.path.join(_local_forder,f"imagen_{request_body_info.prompt}_{1}_{D.date_file_name()}.png"))
# Clean up temporary files # # Clean up temporary files
if 'temp_image_path' in locals(): # if 'temp_image_path' in locals():
if os.path.exists(temp_image_path): # if os.path.exists(temp_image_path):
os.remove(temp_image_path) # os.remove(temp_image_path)
del temp_image_path # del temp_image_path
return response.set_message() # return response.set_message()
except Exception as e: # except Exception as e:
LOG.error(traceback.format_exc()) # LOG.error(traceback.format_exc())
# Clean up temporary files # # Clean up temporary files
if 'query_image_path' in locals(): # if 'query_image_path' in locals():
if os.path.exists(query_image_path): # if os.path.exists(query_image_path):
os.remove(query_image_path) # os.remove(query_image_path)
del query_image_path # del query_image_path
return response.set_error(error=e) # return response.set_error(error=e)
@router.post("/imageGenerate/imagen/data", summary="이미지 생성(AI) - imagen(data)", response_model=M.ImageGenerateDataRes) # @router.post("/imageGenerate/imagen/data", summary="이미지 생성(AI) - imagen(data)", response_model=M.ImageGenerateDataRes)
async def imagen_data(request: Request, request_body_info: M.ImageGenerateReq): # async def imagen_data(request: Request, request_body_info: M.ImageGenerateReq):
""" # """
## 이미지 생성(AI) - imagen # ## 이미지 생성(AI) - imagen
> imagen AI를 이용하여 이미지 데이터생성 # > imagen AI를 이용하여 이미지 데이터생성
""" # """
# imagen 사용중단 gemini로 변경 # # imagen 사용중단 gemini로 변경
response = M.ImageGenerateDataRes() # response = M.ImageGenerateDataRes()
try: # try:
# NOTE(JWKIM) : imagen 사용 중단 # # NOTE(JWKIM) : imagen 사용 중단
# img_length = imagen_generate_image(prompt=request_body_info.prompt, # # img_length = imagen_generate_image(prompt=request_body_info.prompt,
# download_count=request_body_info.downloadCount # # download_count=request_body_info.downloadCount
# ) # # )
temp_image_path = gemini_image(request_body_info.prompt) # temp_image_path = gemini_image(request_body_info.prompt)
b64data = image_to_base64_string(temp_image_path) # b64data = image_to_base64_string(temp_image_path)
# Clean up temporary files # # Clean up temporary files
if 'temp_image_path' in locals(): # if 'temp_image_path' in locals():
if os.path.exists(temp_image_path): # if os.path.exists(temp_image_path):
os.remove(temp_image_path) # os.remove(temp_image_path)
del temp_image_path # del temp_image_path
return response.set_message(b64data) # return response.set_message(b64data)
except Exception as e: # except Exception as e:
LOG.error(traceback.format_exc()) # LOG.error(traceback.format_exc())
# Clean up temporary files # # Clean up temporary files
if 'query_image_path' in locals(): # if 'query_image_path' in locals():
if os.path.exists(query_image_path): # if os.path.exists(query_image_path):
os.remove(query_image_path) # os.remove(query_image_path)
del query_image_path # del query_image_path
return response.set_error(error=e) # return response.set_error(error=e)
# @router.post("/vectorImageSearch/imagenet/imageGenerate/imagen", summary="벡터 이미지 검색(imagenet) - imagen", response_model=M.ResponseBase) # @router.post("/vectorImageSearch/imagenet/imageGenerate/imagen", summary="벡터 이미지 검색(imagenet) - imagen", response_model=M.ResponseBase)
# async def vactor_imagenet(request: Request, request_body_info: M.vectorImageSearchReq): # async def vactor_imagenet(request: Request, request_body_info: M.vectorImageSearchReq):
@@ -256,181 +258,245 @@ async def imagen_data(request: Request, request_body_info: M.ImageGenerateReq):
# LOG.error(traceback.format_exc()) # LOG.error(traceback.format_exc())
# return response.set_error(error=e) # return response.set_error(error=e)
@router.post("/vectorImageSearch/vit/imageGenerate/imagen", summary="벡터 이미지 검색(clip-vit) - imagen", response_model=M.ResponseBase) # @router.post("/vectorImageSearch/vit/imageGenerate/imagen", summary="벡터 이미지 검색(clip-vit) - imagen", response_model=M.ResponseBase)
async def vactor_vit(request: Request, request_body_info: M.VectorImageSearchVitReq): # async def vactor_vit(request: Request, request_body_info: M.VectorImageSearchVitReq):
""" # """
## 벡터 이미지 검색(clip-vit) - imagen # ## 벡터 이미지 검색(clip-vit) - imagen
> imagen AI를 이용하여 이미지 생성 후 vector 검색 그후 결과 이미지 생성 # > imagen AI를 이용하여 이미지 생성 후 vector 검색 그후 결과 이미지 생성
### options # ### options
> - modelType -> b32,b16,l14,l14_336 # > - modelType -> b32,b16,l14,l14_336
> - indexType -> l2,cos # > - indexType -> l2,cos
""" # """
response = M.ResponseBase() # response = M.ResponseBase()
try: # try:
if not download_range(request_body_info.searchNum, max=10): # if not download_range(request_body_info.searchNum, max=10):
raise Exception(f"downloadCound is invalid (current value = {request_body_info.searchNum})") # raise Exception(f"downloadCound is invalid (current value = {request_body_info.searchNum})")
if request_body_info.modelType not in [M.VitModelType.b32, M.VitModelType.b16, M.VitModelType.l14, M.VitModelType.l14_336]: # if request_body_info.modelType not in [M.VitModelType.b32, M.VitModelType.b16, M.VitModelType.l14, M.VitModelType.l14_336]:
raise Exception(f"modelType is invalid (current value = {request_body_info.modelType})") # raise Exception(f"modelType is invalid (current value = {request_body_info.modelType})")
if request_body_info.indexType not in [M.VitIndexType.cos, M.VitIndexType.l2]: # if request_body_info.indexType not in [M.VitIndexType.cos, M.VitIndexType.l2]:
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_path = imagen_generate_temp_image_path(image_prompt=request_body_info.prompt) #imagen # # query_image_path = imagen_generate_temp_image_path(image_prompt=request_body_info.prompt) #imagen
query_image_path = gemini_image(request_body_info.prompt) #gemini # query_image_path = gemini_image(request_body_info.prompt) #gemini
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,
'model_type' : request_body_info.modelType, # 'model_type' : request_body_info.modelType,
'search_num' : request_body_info.searchNum} # 'search_num' : request_body_info.searchNum}
vector_response = requests.post('http://localhost:51002/api/services/faiss/vector/search/vit', data=json.dumps(vector_request_data)) # vector_response = requests.post('http://localhost:51002/api/services/faiss/vector/search/vit', data=json.dumps(vector_request_data))
vector_response_dict = json.loads(vector_response.text) # vector_response_dict = json.loads(vector_response.text)
if vector_response.status_code != 200: # if vector_response.status_code != 200:
raise Exception(f"response error: {vector_response_dict['error']}") # raise Exception(f"response error: {vector_response_dict['error']}")
if vector_response_dict["error"] != None: # if vector_response_dict["error"] != None:
raise Exception(f"vector error: {vector_response_dict['error']}") # raise Exception(f"vector error: {vector_response_dict['error']}")
result_image_paths = vector_response_dict.get('img_list').get('result_image_paths') # result_image_paths = vector_response_dict.get('img_list').get('result_image_paths')
result_percents = vector_response_dict.get('img_list').get('result_percents') # result_percents = vector_response_dict.get('img_list').get('result_percents')
if rest_config.config != 'release': # if rest_config.config != 'release':
# 원격지 폴더 생성 # # 원격지 폴더 생성
remote_directory = os.path.join(rest_config.remote_folder, f"imagen_query_{request_body_info.modelType}_{request_body_info.indexType}_{request_body_info.prompt}_{D.date_file_name()}") # remote_directory = os.path.join(rest_config.remote_folder, f"imagen_query_{request_body_info.modelType}_{request_body_info.indexType}_{request_body_info.prompt}_{D.date_file_name()}")
sftp_client.remote_mkdir(remote_directory) # sftp_client.remote_mkdir(remote_directory)
# 원격지에 이미지 저장 # # 원격지에 이미지 저장
sftp_client.remote_copy_data(local_path=query_image_path, remote_path=os.path.join(remote_directory,"query.png")) # sftp_client.remote_copy_data(local_path=query_image_path, remote_path=os.path.join(remote_directory,"query.png"))
for img_path, img_percent in zip(result_image_paths,result_percents): # for img_path, img_percent in zip(result_image_paths,result_percents):
sftp_client.remote_copy_data(local_path=img_path, remote_path=os.path.join(remote_directory,f"search_{img_percent}.png")) # sftp_client.remote_copy_data(local_path=img_path, remote_path=os.path.join(remote_directory,f"search_{img_percent}.png"))
# else:
# local_directory = os.path.join(rest_config.local_folder, f"imagen_query_{request_body_info.modelType}_{request_body_info.indexType}_{request_body_info.prompt}_{D.date_file_name()}")
# os.makedirs(local_directory, exist_ok=True)
# shutil.copy(query_image_path, os.path.join(local_directory,"query.png"))
# for img_path, img_percent in zip(result_image_paths,result_percents):
# shutil.copy(img_path, os.path.join(local_directory,f"search_{img_percent}.png"))
# # Clean up temporary files
# if 'query_image_path' in locals():
# if os.path.exists(query_image_path):
# os.remove(query_image_path)
# del query_image_path
# return response.set_message()
# except Exception as e:
# LOG.error(traceback.format_exc())
# # Clean up temporary files
# if 'query_image_path' in locals():
# if os.path.exists(query_image_path):
# os.remove(query_image_path)
# del query_image_path
# return response.set_error(error=e)
# @router.post("/vectorImageSearch/vit/imageGenerate/imagen/data", summary="벡터 이미지 검색(clip-vit) - imagen(data)", response_model=M.VectorImageSerachDataRes)
# async def vactor_vit_data(request: Request, request_body_info: M.VectorImageSearchVitDataReq):
# """
# ## 벡터 이미지 검색(clip-vit) - imagen
# > imagen AI를 이용하여 이미지 생성 후 vector 검색 그후 결과 이미지데이터 return
# ### options
# > - modelType -> b32,b16,l14,l14_336
# > - indexType -> l2,cos
# """
# response = M.VectorImageSerachDataRes()
# query_image_data = ''
# try:
# if not download_range(request_body_info.searchNum, max=10):
# raise Exception(f"downloadCound is invalid (current value = {request_body_info.searchNum})")
# if request_body_info.modelType not in [M.VitModelType.b32, M.VitModelType.b16, M.VitModelType.l14, M.VitModelType.l14_336]:
# raise Exception(f"modelType is invalid (current value = {request_body_info.modelType})")
# if request_body_info.indexType not in [M.VitIndexType.cos, M.VitIndexType.l2]:
# raise Exception(f"indexType is invalid (current value = {request_body_info.indexType})")
# # query_image_path = imagen_generate_temp_image_path(image_prompt=request_body_info.prompt) #imagen
# query_image_path = gemini_image(request_body_info.prompt) #gemini
# vector_request_data = {'query_image_path' : query_image_path,
# 'index_type' : request_body_info.indexType,
# 'model_type' : request_body_info.modelType,
# 'search_num' : request_body_info.searchNum}
# vector_response = requests.post('http://localhost:51002/api/services/faiss/vector/search/vit', data=json.dumps(vector_request_data))
# vector_response_dict = json.loads(vector_response.text)
# if vector_response.status_code != 200:
# raise Exception(f"response error: {vector_response_dict['error']}")
# if vector_response_dict["error"] != None:
# raise Exception(f"vector error: {vector_response_dict['error']}")
# result_image_paths = vector_response_dict.get('img_list').get('result_image_paths')
# result_percents = vector_response_dict.get('img_list').get('result_percents')
# # 이미지 데이터 생성
# vector_image_results = []
# for img, percents in zip(result_image_paths, result_percents):
# b64_data = image_to_base64_string(img)
# float_percent = float(percents)
# info = M.VectorImageResult(image=b64_data,percents=float_percent)
# vector_image_results.append(info)
# if request_body_info.querySend:
# query_image_data = image_to_base64_string(query_image_path)
# # Clean up temporary files
# if 'query_image_path' in locals():
# if os.path.exists(query_image_path):
# os.remove(query_image_path)
# del query_image_path
# return response.set_message(vector_result=vector_image_results,query_img=query_image_data)
# except Exception as e:
# LOG.error(traceback.format_exc())
# # Clean up temporary files
# if 'query_image_path' in locals():
# if os.path.exists(query_image_path):
# os.remove(query_image_path)
# del query_image_path
# return response.set_error(error=e)
@router.post("/imageGenerator", summary="이미지 데이터 생성", response_model=M.ImageGenerateDataRes)
async def image_generator(request: Request, request_body_info: M.ImageGenerateReq):
"""
## 이미지 생성
> 입력된 prompt로 이미지 생성 그후 결과 이미지데이터 return
### Input
> 접두어(prefix)는 null값을 주어도 기본값 사용, 빈("")값 사용시 prefix는 사용안함
> 최종 입력시 prefix, prompt 조합하여 내부적으로 최종 문장 완성
### Output
> - 결과(imageData)는 base64로 변환된 데이터(image)
### Options
> - prefix -> 접두어 (기본값: 하얀색 배경)
> - prompt -> 프롬프트
### Notice
> - 최종이미지에 배경이 없어야 이미지 검색시 유리하기때문에 꼭 prefix 옵션은 사용
"""
response = M.ImageGenerateDataRes()
try:
if request_body_info.prefix == None:
request_body_info.prefix = M.ImageGenerateReq.model_fields.get("prefix").default
full_prompt = f"{request_body_info.prefix}, {request_body_info.prompt}" if request_body_info.prefix else f"{request_body_info.prompt}"
temp_image_path = gemini_image(full_prompt)
if os.path.exists(temp_image_path):
image_data = image_to_base64_string(temp_image_path)
# Clean up temporary files
if 'temp_image_path' in locals():
if os.path.exists(temp_image_path):
os.remove(temp_image_path)
del temp_image_path
return response.set_message(image_data)
else: else:
local_directory = os.path.join(rest_config.local_folder, f"imagen_query_{request_body_info.modelType}_{request_body_info.indexType}_{request_body_info.prompt}_{D.date_file_name()}") raise Exception(f"image not generated(prefix: {request_body_info.prefix}, prompt:{request_body_info.prompt})")
os.makedirs(local_directory, exist_ok=True)
shutil.copy(query_image_path, os.path.join(local_directory,"query.png"))
for img_path, img_percent in zip(result_image_paths,result_percents):
shutil.copy(img_path, os.path.join(local_directory,f"search_{img_percent}.png"))
# Clean up temporary files
if 'query_image_path' in locals():
if os.path.exists(query_image_path):
os.remove(query_image_path)
del query_image_path
return response.set_message()
except Exception as e: except Exception as e:
LOG.error(traceback.format_exc()) LOG.error(traceback.format_exc())
# Clean up temporary files # Clean up temporary files
if 'query_image_path' in locals(): if 'temp_image_path' in locals():
if os.path.exists(query_image_path): if os.path.exists(temp_image_path):
os.remove(query_image_path) os.remove(temp_image_path)
del query_image_path del temp_image_path
return response.set_error(error=e) return response.set_error(error=e)
@router.post("/vectorImageSearch/vit/imageGenerate/imagen/data", summary="벡터 이미지 검색(clip-vit) - imagen(data)", response_model=M.VectorImageSerachDataRes)
async def vactor_vit_data(request: Request, request_body_info: M.VectorImageSearchVitDataReq): @router.post("/vectorImageSearch/vit/inputImage/data/glasses", summary="벡터 이미지 검색(clip-vit) - input image(data): glasses", response_model=M.VectorGlassesImageSerachDataRes)
async def vactor_vit_input_glasses_img_data(request: Request, request_body_info: M.VectorGlassesImageSearchVitInputImgReq):
""" """
## 벡터 이미지 검색(clip-vit) - imagen ## 벡터 이미지 검색(clip-vit) - inputimage : glasses
> imagen AI를 이용하여 이미지 생성 후 vector 검색 그후 결과 이미지데이터 return
### options
> - modelType -> b32,b16,l14,l14_336
> - indexType -> l2,cos
"""
response = M.VectorImageSerachDataRes()
query_image_data = ''
try:
if not download_range(request_body_info.searchNum, max=10):
raise Exception(f"downloadCound is invalid (current value = {request_body_info.searchNum})")
if request_body_info.modelType not in [M.VitModelType.b32, M.VitModelType.b16, M.VitModelType.l14, M.VitModelType.l14_336]:
raise Exception(f"modelType is invalid (current value = {request_body_info.modelType})")
if request_body_info.indexType not in [M.VitIndexType.cos, M.VitIndexType.l2]:
raise Exception(f"indexType is invalid (current value = {request_body_info.indexType})")
# query_image_path = imagen_generate_temp_image_path(image_prompt=request_body_info.prompt) #imagen
query_image_path = gemini_image(request_body_info.prompt) #gemini
vector_request_data = {'query_image_path' : query_image_path,
'index_type' : request_body_info.indexType,
'model_type' : request_body_info.modelType,
'search_num' : request_body_info.searchNum}
vector_response = requests.post('http://localhost:51002/api/services/faiss/vector/search/vit', data=json.dumps(vector_request_data))
vector_response_dict = json.loads(vector_response.text)
if vector_response.status_code != 200:
raise Exception(f"response error: {vector_response_dict['error']}")
if vector_response_dict["error"] != None:
raise Exception(f"vector error: {vector_response_dict['error']}")
result_image_paths = vector_response_dict.get('img_list').get('result_image_paths')
result_percents = vector_response_dict.get('img_list').get('result_percents')
# 이미지 데이터 생성
vector_image_results = []
for img, percents in zip(result_image_paths, result_percents):
b64_data = image_to_base64_string(img)
float_percent = float(percents)
info = M.VectorImageResult(image=b64_data,percents=float_percent)
vector_image_results.append(info)
if request_body_info.querySend:
query_image_data = image_to_base64_string(query_image_path)
# Clean up temporary files
if 'query_image_path' in locals():
if os.path.exists(query_image_path):
os.remove(query_image_path)
del query_image_path
return response.set_message(vector_result=vector_image_results,query_img=query_image_data)
except Exception as e:
LOG.error(traceback.format_exc())
# Clean up temporary files
if 'query_image_path' in locals():
if os.path.exists(query_image_path):
os.remove(query_image_path)
del query_image_path
return response.set_error(error=e)
@router.post("/vectorImageSearch/vit/inputImage/data", summary="벡터 이미지 검색(clip-vit) - input image(data)", response_model=M.VectorImageSerachDataRes)
async def vactor_vit_input_img_data(request: Request, request_body_info: M.VectorImageSearchVitInputImgReq):
"""
## 벡터 이미지 검색(clip-vit) - inputimage
> 입력된 이미지로 vector 검색 그후 결과 이미지데이터 return > 입력된 이미지로 vector 검색 그후 결과 이미지데이터 return
### Requriements ### Input
> - googlecli 설치(https://cloud.google.com/sdk/docs/install?hl=ko#linux) > 입력이미지(inputImage)는 base64로 변환된 데이터 입력
### options ### Output
> - modelType -> b32,b16,l14,l14_336 > - 결과(vectorResult)는 base64로 변환된 데이터(image), 유사도(percents), 파츠정보(parts)가 쌍으로 나오며, 요청한 searchNum 갯수에 맞춰서 결과가 나옴
> - indexType -> l2,cos > - queryImage는 Input시 입력한 inputImage 이미지 데이터
### Options
> - modelType -> b32, b16, l14, l14_336 (기본값: b32)
> - indexType -> l2, cos (기본값: l2)
> - searchNum -> 결과이미지 갯수 (기본값: 4)
### Notice
> - 일반검색시 indexType , modelType 은 기본값으로 사용
> - indexType , modelType - 새로운 조합 (ex l14, cos)으로 처음 요청할경우 모델을 빌드하는 과정이 추가됨
""" """
response = M.VectorImageSerachDataRes() response = M.VectorGlassesImageSerachDataRes()
query_image_data = '' query_image_data = ''
try: try:
@@ -440,7 +506,9 @@ async def vactor_vit_input_img_data(request: Request, request_body_info: M.Vecto
if request_body_info.indexType not in [M.VitIndexType.cos, M.VitIndexType.l2]: if request_body_info.indexType not in [M.VitIndexType.cos, M.VitIndexType.l2]:
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_path = os.path.join(TEMP_FOLDER, f'input_{D.date_file_name()}_query.png') query_image_path = os.path.join(TEMP_FOLDER, f'input_{D.date_file_name()}_query.png')
os.makedirs(TEMP_FOLDER, exist_ok=True)
save_base64_as_image_file(request_body_info.inputImage ,query_image_path) save_base64_as_image_file(request_body_info.inputImage ,query_image_path)
vector_request_data = {'query_image_path' : query_image_path, vector_request_data = {'query_image_path' : query_image_path,
@@ -453,21 +521,25 @@ async def vactor_vit_input_img_data(request: Request, request_body_info: M.Vecto
vector_response_dict = json.loads(vector_response.text) vector_response_dict = json.loads(vector_response.text)
if vector_response.status_code != 200: if vector_response.status_code != 200:
raise Exception(f"response error: {vector_response_dict['error']}") raise Exception(f"search server error: {vector_response_dict['error']}")
if vector_response_dict["error"] != None: if vector_response_dict["error"] != None:
raise Exception(f"vector error: {vector_response_dict['error']}") raise Exception(f"search result error: {vector_response_dict['error']}")
result_image_paths = vector_response_dict.get('img_list').get('result_image_paths') result_image_paths = vector_response_dict.get('img_list').get('result_image_paths')
result_percents = vector_response_dict.get('img_list').get('result_percents') result_percents = vector_response_dict.get('img_list').get('result_percents')
result_parts = vector_response_dict.get('img_list').get('result_parts_list')
# 이미지 데이터 생성 # 이미지 데이터 생성
vector_image_results = [] vector_image_results = []
for img, percents in zip(result_image_paths, result_percents): for img, percents, parts in zip(result_image_paths, result_percents, result_parts):
b64_data = image_to_base64_string(img)
b64_data = None
if os.path.exists(img):
b64_data = image_to_base64_string(img)
float_percent = float(percents) float_percent = float(percents)
info = M.VectorImageResult(image=b64_data,percents=float_percent) info = M.VectorGlassesImageResult(image=b64_data, percents=float_percent, imageInfo=os.path.split(img)[-1], parts=parts)
vector_image_results.append(info) vector_image_results.append(info)
@@ -491,75 +563,75 @@ async def vactor_vit_input_img_data(request: Request, request_body_info: M.Vecto
return response.set_error(error=e) return response.set_error(error=e)
@router.post("/vectorImageSearch/vit/imageGenerate/imagen/report", summary="벡터 이미지 검색(clip-vit) - imagen, report 생성", response_model=M.ResponseBase) @router.post("/vectorImageSearch/vit/inputImage/data/parts", summary="벡터 이미지 검색(clip-vit) - input image(data): parts", response_model=M.VectorPartsImageSerachDataRes)
async def vactor_vit_report(request: Request, request_body_info: M.VectorImageSearchVitReportReq): async def vactor_vit_input_parts_img_data(request: Request, request_body_info: M.VectorPartsImageSearchVitInputImgReq):
""" """
## 벡터 이미지 검색(clip-vit) - imagen, report 생성 ## 벡터 이미지 검색(clip-vit) - inputImage : parts
> imagen AI를 이용하여 이미지 생성 후 vector 검색 그후 종합결과 이미지 생성 > 입력된 이미지로 vector 검색 그후 결과 이미지데이터 return
### Requriements ### Input
> - googlecli 설치(https://cloud.google.com/sdk/docs/install?hl=ko#linux) > 입력이미지(inputImage)는 파츠 이미지파일 이름 (확장자 포함)
> ⚠️ /vectorImageSearch/vit/inputImage/data/glasses API response인 parts 값중 하나를 선택
### options ### Output
> - modelType -> b32,b16,l14,l14_336 > - 결과(vectorResult)는 base64로 변환된 데이터(image), 유사도(percents)가 쌍으로 나오며, 요청한 searchNum 갯수에 맞춰서 결과가 나옴
> - indexType -> l2,cos > - queryImage는 Input시 입력한 inputImage 이미지 데이터
### Options
> - modelType -> b32, b16, l14, l14_336 (기본값: b32)
> - indexType -> l2, cos (기본값: l2)
> - searchNum -> 결과이미지 갯수 (기본값: 4)
### Notice
> - 일반검색시 indexType , modelType 은 기본값으로 사용
> - indexType , modelType, inputImage - 새로운 조합 (ex l14, cos, Lens)으로 처음 요청할경우 모델을 빌드하는 과정이 추가됨
""" """
response = M.ResponseBase() response = M.VectorPartsImageSerachDataRes()
try: try:
if request_body_info.modelType not in [M.VitModelType.b32, M.VitModelType.b16, M.VitModelType.l14, M.VitModelType.l14_336]: if request_body_info.modelType not in [M.VitModelType.b32, M.VitModelType.b16, M.VitModelType.l14, M.VitModelType.l14_336]:
raise Exception(f"modelType is invalid (current value = {request_body_info.modelType})") raise Exception(f"modelType is invalid (current value = {request_body_info.modelType})")
if request_body_info.indexType not in [M.VitIndexType.cos, M.VitIndexType.l2]: if request_body_info.indexType not in [M.VitIndexType.cos, M.VitIndexType.l2]:
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_path = imagen_generate_temp_image_path(image_prompt=request_body_info.prompt) #imagen glass_name = f"{request_body_info.inputImage.split('_')[0]}_{request_body_info.inputImage.split('_')[1]}"
query_image_path = gemini_image(request_body_info.prompt) #gemini query_image_path = os.path.join(IMG_LIST_PATH, glass_name, ImageDepths.parts, request_body_info.inputImage)
report_image_path = f"{os.path.splitext(query_image_path)[0]}_report.png" query_image_data = image_to_base64_string(query_image_path)
vactor_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,
'model_type' : request_body_info.modelType, 'model_type' : request_body_info.modelType,
'report_path' : report_image_path} 'search_num' : request_body_info.searchNum}
vactor_response = requests.post('http://localhost:51002/api/services/faiss/vector/search/vit/report', data=json.dumps(vactor_request_data)) vector_response = requests.post('http://localhost:51002/api/services/faiss/vector/search/vit/parts', data=json.dumps(vector_request_data))
if vactor_response.status_code != 200: vector_response_dict = json.loads(vector_response.text)
raise Exception(f"response error: {json.loads(vactor_response.text)['error']}")
if json.loads(vactor_response.text)["error"] != None: if vector_response.status_code != 200:
raise Exception(f"vector error: {json.loads(vactor_response.text)['error']}") raise Exception(f"search server error: {vector_response_dict['error']}")
if rest_config.config != 'release': if vector_response_dict["error"] != None:
# remote 폴더에 이미지 저장 raise Exception(f"search result error: {vector_response_dict['error']}")
sftp_client.remote_copy_data(local_path=report_image_path,
remote_path=os.path.join(rest_config.remote_folder, f"imagen_report_vit_{request_body_info.prompt}_{D.date_file_name()}.png"))
else:
shutil.copy(report_image_path, os.path.join(rest_config.local_folder, f"imagen_report_vit_{request_body_info.prompt}_{D.date_file_name()}.png"))
# Clean up temporary files
if 'query_image_path' in locals():
if os.path.exists(query_image_path):
os.remove(query_image_path)
del query_image_path
if 'report_image_path' in locals():
if os.path.exists(report_image_path):
os.remove(report_image_path)
del report_image_path
return response.set_message() result_image_paths = vector_response_dict.get('img_list').get('result_image_paths')
result_percents = vector_response_dict.get('img_list').get('result_percents')
# 이미지 데이터 생성
vector_image_results = []
for img, percents in zip(result_image_paths, result_percents):
b64_data = None
if os.path.exists(img):
b64_data = image_to_base64_string(img)
float_percent = float(percents)
info = M.VectorPartsImageResult(image=b64_data, percents=float_percent, imageInfo=os.path.split(img)[-1])
vector_image_results.append(info)
return response.set_message(vector_result=vector_image_results,query_img=query_image_data)
except Exception as e: except Exception as e:
LOG.error(traceback.format_exc()) LOG.error(traceback.format_exc())
# Clean up temporary files
if 'query_image_path' in locals():
if os.path.exists(query_image_path):
os.remove(query_image_path)
del query_image_path
if 'report_image_path' in locals():
if os.path.exists(report_image_path):
os.remove(report_image_path)
del report_image_path
return response.set_error(error=e) return response.set_error(error=e)

View File

@@ -65,8 +65,10 @@ def save_base64_as_image_file(base64_data: str, output_path: str):
""" """
Base64 문자열을 디코딩하여 이미지 파일로 저장합니다. Base64 문자열을 디코딩하여 이미지 파일로 저장합니다.
""" """
# Base64 문자열을 디코딩하여 이진 데이터로 변환합니다. try:
decoded_data = base64.b64decode(base64_data) # Base64 문자열을 디코딩하여 이진 데이터로 변환합니다.
with open(output_path, "wb") as image_file: decoded_data = base64.b64decode(base64_data)
image_file.write(decoded_data) with open(output_path, "wb") as image_file:
image_file.write(decoded_data)
except Exception as e:
raise Exception(f"input image data error : {e}")

117
make_vector_files.py Normal file
View File

@@ -0,0 +1,117 @@
# from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.faiss_functions import get_clip_info
import os
from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.faiss_similarity_search import VectorSimilarity
from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.const import *
from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.faiss_functions import get_models, find_glass_folder_images, find_parts_folder_images
from vector_rest.app import models as VM
def make_image_files(item_info, index_type:VM.VitIndexType, model_type:VM.VitModelType):
model = get_models(index_type=index_type, model_type=model_type)
txt_file_path = os.path.join(FAISS_VECTOR_PATH,f'{model.name}_{os.path.basename(model.value[1].trained_model)}_{model.value[1].index_type}_{item_info}.txt')
image_lists = []
if not os.path.exists(txt_file_path):
if item_info == VectorSearchItem.glass:
image_lists = find_glass_folder_images(IMG_LIST_PATH)
else:
image_lists = find_parts_folder_images(IMG_LIST_PATH, item_info)
if image_lists:
with open(txt_file_path, 'w') as f:
for img_path in image_lists:
f.write(f"{img_path}\n")
else:
temp_path = os.path.join(FAISS_VECTOR_PATH,f'{model.name}_{os.path.basename(model.value[1].trained_model)}_{model.value[1].index_type}_{item_info}.bak')
try:
os.rename(txt_file_path, temp_path)
if item_info == VectorSearchItem.glass:
image_lists = find_glass_folder_images(IMG_LIST_PATH)
else:
image_lists = find_parts_folder_images(IMG_LIST_PATH, item_info)
if image_lists:
with open(txt_file_path, 'w') as f:
for img_path in image_lists:
f.write(f"{img_path}\n")
except Exception as e:
print(f"Error updating image file list: {e}")
finally:
if os.path.exists(txt_file_path):
os.remove(temp_path)
else:
os.rename(temp_path, txt_file_path)
return txt_file_path
def make_vector_files(item_info, index_type:VM.VitIndexType, model_type:VM.VitModelType):
model = get_models(index_type=index_type, model_type=model_type)
txt_file_path = make_image_files(item_info=item_info, index_type=index_type, model_type=model_type)
index_file_path = os.path.join(IMG_LIST_PATH,f'{model.name}_{os.path.basename(model.value[1].trained_model)}_{model.value[1].index_type}_{item_info}_{DEFAULT_INDEX_NAME_SUFFIX}')
if not os.path.exists(index_file_path):
vector_model = VectorSimilarity(model_info=model,
index_file_path=index_file_path,
txt_file_path=txt_file_path)
with open(txt_file_path, 'r') as f:
image_lists = [line.strip() for line in f.readlines()]
vector_model.save_index_from_files(images_path_lists=image_lists,
save_index_dir=FAISS_VECTOR_PATH,
save_txt_dir=IMG_LIST_PATH,
item_info=item_info,
index_type=model.value[1].index_type)
else:
temp_path = os.path.join(IMG_LIST_PATH,f'{model.name}_{os.path.basename(model.value[1].trained_model)}_{model.value[1].index_type}_{item_info}_{DEFAULT_INDEX_NAME_SUFFIX}.bak')
try:
os.rename(index_file_path, temp_path)
vector_model = VectorSimilarity(model_info=model,
index_file_path=index_file_path,
txt_file_path=txt_file_path)
with open(txt_file_path, 'r') as f:
image_lists = [line.strip() for line in f.readlines()]
vector_model.save_index_from_files(images_path_lists=image_lists,
save_index_dir=FAISS_VECTOR_PATH,
save_txt_dir=IMG_LIST_PATH,
item_info=item_info,
index_type=model.value[1].index_type)
except Exception as e:
print(f"Error updating vector file: {e}")
finally:
if os.path.exists(index_file_path):
os.remove(temp_path)
else:
os.rename(temp_path, index_file_path)
print(f"Vector file created: {index_file_path} :::::::::: item_info: {item_info}, index_type: {index_type}, model_type: {model_type}")
return index_file_path
if __name__ == '__main__':
import time
class_attributes = dict(VectorSearchItem.__dict__)
pure_data_dict = {
key: value
for key, value in class_attributes.items()
if not key.startswith('__')
}
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)
time.sleep(5) # huggingface api 요청 제한 회피 위해 대기 TODO(jwkim) huggingface 로그인은 한번만 진행하게 변경

View File

@@ -8,6 +8,7 @@
- 2022-01-14/hsj100@a2tec.co.kr : refactoring - 2022-01-14/hsj100@a2tec.co.kr : refactoring
@brief: consts @brief: consts
""" """
from config import rest_config
# SUPPORT PROJECT # SUPPORT PROJECT
SUPPORT_PROJECT_BASIC = 'PROJECT_BASIC' SUPPORT_PROJECT_BASIC = 'PROJECT_BASIC'
@@ -87,7 +88,7 @@ NUM_RETRY_UUID_GEN = 3
DB_ADDRESS = "localhost" DB_ADDRESS = "localhost"
DB_PORT = 53306 DB_PORT = 53306
DB_USER_ID = 'root' DB_USER_ID = 'root'
DB_USER_PW = '1234' DB_USER_PW = rest_config.db_pw
DB_NAME = 'FM_TEST' DB_NAME = 'FM_TEST'
DB_CHARSET = 'utf8mb4' DB_CHARSET = 'utf8mb4'

View File

@@ -583,7 +583,7 @@ class VitModelType(str, Enum):
l14_336 = "l14_336" l14_336 = "l14_336"
class VactorSearchReq(BaseModel): class VectorSearchReq(BaseModel):
""" """
### [Request] vector 검색 ### [Request] vector 검색
""" """
@@ -592,7 +592,7 @@ class VactorSearchReq(BaseModel):
search_num : int = Field(4, description='검색결과 이미지 갯수', example=4) search_num : int = Field(4, description='검색결과 이미지 갯수', example=4)
class VactorSearchVitReportReq(BaseModel): class VectorSearchVitReportReq(BaseModel):
""" """
### [Request] vector 검색(vit) 후 리포트 이미지 생성 ### [Request] vector 검색(vit) 후 리포트 이미지 생성
""" """
@@ -602,7 +602,7 @@ class VactorSearchVitReportReq(BaseModel):
report_path : str = Field(description='리포트 이미지 저장 경로', example='path') report_path : str = Field(description='리포트 이미지 저장 경로', example='path')
class VactorSearchVitReq(BaseModel): class VectorSearchVitReq(BaseModel):
""" """
### [Request] vector 검색(vit) 후 이미지 생성 ### [Request] vector 검색(vit) 후 이미지 생성
""" """
@@ -611,22 +611,21 @@ class VactorSearchVitReq(BaseModel):
model_type : VitModelType = Field(VitModelType.l14, description='pretrained 모델 정보', example=VitModelType.l14) model_type : VitModelType = Field(VitModelType.l14, description='pretrained 모델 정보', example=VitModelType.l14)
search_num : int = Field(4, description='검색결과 이미지 갯수', example=4) search_num : int = Field(4, description='검색결과 이미지 갯수', example=4)
class VectorSearchVitRes(ResponseBase):
class VactorSearchVitRes(ResponseBase):
img_list : dict = Field({}, description='이미지 결과 리스트', example={}) img_list : dict = Field({}, description='이미지 결과 리스트', example={})
@staticmethod @staticmethod
def set_error(error): def set_error(error):
VactorSearchVitRes.img_list = {} VectorSearchVitRes.img_list = {}
VactorSearchVitRes.result = False VectorSearchVitRes.result = False
VactorSearchVitRes.error = str(error) VectorSearchVitRes.error = str(error)
return VactorSearchVitRes return VectorSearchVitRes
@staticmethod @staticmethod
def set_message(msg): def set_message(msg):
VactorSearchVitRes.img_list = msg VectorSearchVitRes.img_list = msg
VactorSearchVitRes.result = True VectorSearchVitRes.result = True
VactorSearchVitRes.error = None VectorSearchVitRes.error = None
return VactorSearchVitRes return VectorSearchVitRes

View File

@@ -39,7 +39,7 @@ def send_mail():
sender = 'jolimola@gmail.com' sender = 'jolimola@gmail.com'
sender_pw = '!ghkdtmdwns1' sender_pw = '!ghkdtmdwns1'
# recipient = 'hsj100@a2tec.co.kr' # recipient = 'hsj100@a2tec.co.kr'
recipient = 'jwkim@daooldns.co.kr' recipient = 'jwkim@a2tec.co.kr'
list_cc = ['cc1@gmail.com', 'cc2@naver.com'] list_cc = ['cc1@gmail.com', 'cc2@naver.com']
str_cc = ','.join(list_cc) str_cc = ','.join(list_cc)

View File

@@ -23,12 +23,14 @@ from custom_apps.faiss_imagenet.main import search_idxs
from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.faiss_functions import get_clip_info, save_report_image, get_models from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.faiss_functions import get_clip_info, save_report_image, get_models
from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.faiss_similarity_search import FEMUsageInfo from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.faiss_similarity_search import FEMUsageInfo
from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.const import VectorSearchItem
from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.utils import search_glass_parts, file_name_to_parts
router = APIRouter(prefix="/services") router = APIRouter(prefix="/services")
@router.post("/faiss/vector/search/imagenet", summary="imagenet search", response_model=M.ResponseBase) @router.post("/faiss/vector/search/imagenet", summary="imagenet search", response_model=M.ResponseBase)
async def vactor_search(request: Request, request_body_info: M.VactorSearchReq): async def vactor_search(request: Request, request_body_info: M.VectorSearchReq):
""" """
## 벡터검색 ## 벡터검색
@@ -54,7 +56,7 @@ async def vactor_search(request: Request, request_body_info: M.VactorSearchReq):
@router.post("/faiss/vector/search/vit/report", summary="vit search report", response_model=M.ResponseBase) @router.post("/faiss/vector/search/vit/report", summary="vit search report", response_model=M.ResponseBase)
async def vactor_report_vit(request: Request, request_body_info: M.VactorSearchVitReportReq): async def vactor_report_vit(request: Request, request_body_info: M.VectorSearchVitReportReq):
""" """
이미지 경로를 입력받아 repport image 저장 이미지 경로를 입력받아 repport image 저장
""" """
@@ -75,23 +77,58 @@ async def vactor_report_vit(request: Request, request_body_info: M.VactorSearchV
return response.set_error(e) return response.set_error(e)
@router.post("/faiss/vector/search/vit", summary="vit search", response_model=M.VactorSearchVitRes) @router.post("/faiss/vector/search/vit", summary="vit search", response_model=M.VectorSearchVitRes)
async def vactor_vit(request: Request, request_body_info: M.VactorSearchVitReq): async def vactor_vit(request: Request, request_body_info: M.VectorSearchVitReq):
""" """
이미지 경로 를 입력받아 vit 방식으로 검색 이미지 경로 를 입력받아 vit 방식으로 검색
""" """
response = M.VactorSearchVitRes() 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)
report_info = get_clip_info(model,request_body_info.query_image_path,top_k=request_body_info.search_num) report_info = get_clip_info(model=model,
query_image_path=request_body_info.query_image_path,
item_info=VectorSearchItem.glass,
top_k=request_body_info.search_num)
parts = search_glass_parts(report_info.result_image_paths)
return response.set_message({ return response.set_message({
'result_image_paths': report_info.result_image_paths, 'result_image_paths': report_info.result_image_paths,
'result_percents': report_info.result_percents 'result_percents': report_info.result_percents,
'result_parts_list': parts
})
except Exception as e:
LOG.error(traceback.format_exc())
return response.set_error(e)
@router.post("/faiss/vector/search/vit/parts", summary="vit search parts", response_model=M.VectorSearchVitRes)
async def vactor_vit_parts(request: Request, request_body_info: M.VectorSearchVitReq):
"""
이미지 경로 를 입력받아 vit 방식으로 parts 검색
"""
response = M.VectorSearchVitRes()
try:
if not os.path.exists(request_body_info.query_image_path):
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)
parts = file_name_to_parts(request_body_info.query_image_path)
report_info = get_clip_info(model=model,
query_image_path=request_body_info.query_image_path,
item_info=parts,
top_k=request_body_info.search_num)
return response.set_message({
'result_image_paths': report_info.result_image_paths,
'result_percents': report_info.result_percents,
}) })
except Exception as e: except Exception as e: