edit: api 변경 - 벡터이미지검색 -> 결과물에 parts 추가, 파츠검색 api 추가

This commit is contained in:
2025-11-27 15:27:22 +09:00
parent 12b12a95f5
commit 18b24dcafa
10 changed files with 384 additions and 145 deletions

View File

@@ -135,3 +135,75 @@ async def test(request: Request):
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 const import TEMP_FOLDER
from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.const import *
router = APIRouter(prefix="/services")
# @router.post("/bing/cookie/set", summary="bing 관련 쿠키 set", response_model=M.BingCookieSetRes)
@@ -471,10 +473,10 @@ async def image_generator(request: Request, request_body_info: M.ImageGenerateRe
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):
@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) - inputimage
## 벡터 이미지 검색(clip-vit) - inputimage : glasses
> 입력된 이미지로 vector 검색 그후 결과 이미지데이터 return
### Input
@@ -494,7 +496,7 @@ async def vactor_vit_input_img_data(request: Request, request_body_info: M.Vecto
> - indexType , modelType - 새로운 조합 (ex l14, cos)으로 처음 요청할경우 모델을 빌드하는 과정이 추가됨
"""
response = M.VectorImageSerachDataRes()
response = M.VectorGlassesImageSerachDataRes()
query_image_data = ''
try:
@@ -526,15 +528,16 @@ async def vactor_vit_input_img_data(request: Request, request_body_info: M.Vecto
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_parts = vector_response_dict.get('img_list').get('result_parts_list')
# 이미지 데이터 생성
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)
float_percent = float(percents)
info = M.VectorImageResult(image=b64_data, percents=float_percent, imageInfo=os.path.split(img)[-1])
info = M.VectorGlassesImageResult(image=b64_data, percents=float_percent, imageInfo=os.path.split(img)[-1], parts=parts)
vector_image_results.append(info)
@@ -558,75 +561,72 @@ async def vactor_vit_input_img_data(request: Request, request_body_info: M.Vecto
return response.set_error(error=e)
# @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):
@router.post("/vectorImageSearch/vit/inputImage/data/parts", summary="벡터 이미지 검색(clip-vit) - input image(data): parts", response_model=M.VectorPartsImageSerachDataRes)
async def vactor_vit_input_parts_img_data(request: Request, request_body_info: M.VectorPartsImageSearchVitInputImgReq):
"""
## 벡터 이미지 검색(clip-vit) - imagen, report 생성
> imagen AI를 이용하여 이미지 생성 후 vector 검색 그후 종합결과 이미지 생성
## 벡터 이미지 검색(clip-vit) - inputImage : parts
> 입력된 이미지로 vector 검색 그후 결과 이미지데이터 return
### Requriements
> - googlecli 설치(https://cloud.google.com/sdk/docs/install?hl=ko#linux)
### Input
> 입력이미지(inputImage)는 파츠이미지 이름 (확장자 포함)
### options
> - modelType -> b32,b16,l14,l14_336
> - indexType -> l2,cos
### Output
> - 결과(vectorResult)는 base64로 변환된 데이터(image), 유사도(percents)가 쌍으로 나오며, 요청한 searchNum 갯수에 맞춰서 결과가 나옴
> - 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()
try:
response = M.VectorPartsImageSerachDataRes()
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,
glass_name = f"{request_body_info.inputImage.split('_')[0]}_{request_body_info.inputImage.split('_')[1]}"
query_image_path = os.path.join(VECTOR_IMG_LIST_PATH, glass_name, ImageDepths.parts, request_body_info.inputImage)
query_image_data = image_to_base64_string(query_image_path)
vector_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}
'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:
raise Exception(f"response error: {json.loads(vactor_response.text)['error']}")
vector_response_dict = json.loads(vector_response.text)
if json.loads(vactor_response.text)["error"] != None:
raise Exception(f"vector error: {json.loads(vactor_response.text)['error']}")
if vector_response.status_code != 200:
raise Exception(f"search server error: {vector_response_dict['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
if vector_response_dict["error"] != None:
raise Exception(f"search result error: {vector_response_dict['error']}")
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 = 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:
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)