Skip to content
Snippets Groups Projects
Commit a71098af authored by Hyunseok_Sang's avatar Hyunseok_Sang
Browse files

테스트 코드 업로드

기능
- 마스크 생성
- 아웃페인팅
- 원본 적용
미구현
- 얼굴 인식
- 객체 탐지
- 데이터베이스에 기록
parent 41e2243f
No related branches found
No related tags found
No related merge requests found
%% Cell type:code id: tags:
``` python
import cv2
import onnxruntime
import numpy as np
import requests
import subprocess
ratio = 55
ratio *= 10
def download_image(url, file_path):
response = requests.get(url)
if response.status_code == 200:
with open(file_path, 'wb') as file:
file.write(response.content)
print("이미지 다운로드 완료")
else:
print("이미지 다운로드 실패")
```
%% Cell type:code id: tags:
``` python
# 이미지 로드
## 원본 이미지를 수정해서는 안됨.
image_path = "남자.jpg"
original = cv2.imread(image_path)
original_height, original_width = original.shape[0], original.shape[1]
```
%% Cell type:code id: tags:
``` python
# 마스크 생성
#-------------------------------------------------
# 모델 로드
model = onnxruntime.InferenceSession('unet.onnx')
mask = cv2.resize(original, (320, 320))
mask = mask.transpose((2, 0, 1)) # 채널 순서 변경
mask = mask.astype(np.float32) / 255.0 # 정규화
mask = np.expand_dims(mask, axis=0) # 배치 차원 추가
# 모델 추론
input_name = model.get_inputs()[0].name
output_name = model.get_outputs()[0].name
mask = model.run([output_name], {input_name: mask})[0]
# 후처리
mask = mask[0, 0, :, :] # 배치와 채널 차원 제거
mask = cv2.resize(mask, (original_width, original_height)) # 원래 크기로 복원. 이 마스크는 확장 영역을 선택할 때 쓰임.
mask = (mask > 0.5).astype(np.uint8) * 255 # 이진화
cv2.imwrite('mask.png', mask)
```
%% Output
True
%% Cell type:code id: tags:
``` python
# 이미지 안의 사람의 크기 구함
## 마스크 이용
#-------------------------------------------------
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
all_contours = []
for c in contours:
all_contours.extend(c)
rect = cv2.minAreaRect(np.array(all_contours))
box = cv2.boxPoints(rect)
box = np.intp(box)
# 왼쪽 위를 기준으로 (x,y) 좌표, w(너비)와 h(높이) 형태로 결과 출력
object_x = box[0][0]
object_y = box[0][1]
object_w = box[2][0] - box[0][0] + 1
object_h = box[2][1] - box[0][1] + 1
```
%% Cell type:code id: tags:
``` python
# 아웃 페인팅하기 위해 1024*1024 이미지로 크기 조정
## 사람의 크기 이용
outpainting = cv2.cvtColor(original, cv2.COLOR_RGB2RGBA)
#객체의 긴 길이 구하기
if object_w > object_h:
longer = object_w
else:
longer = object_h
#인물의 객체의 긴 길이가 55%, 1024*1024에서 ratio픽셀을 차지하도록 설정
new_width, new_height = int(outpainting.shape[1]*ratio/longer), int(outpainting.shape[0]*ratio/longer)
outpainting = cv2.resize(outpainting, (new_width, new_height))
base_image = np.zeros((1024, 1024, 4), dtype=np.uint8)
x_offset = int((base_image.shape[1] - outpainting.shape[1]) / 2)
y_offset = int((base_image.shape[0] - outpainting.shape[0]) / 2)
base_image[y_offset:y_offset + outpainting.shape[0], x_offset:x_offset + outpainting.shape[1]] = outpainting
outpainting = base_image
cv2.imwrite('outpainting.png', outpainting )
```
%% Output
True
%% Cell type:code id: tags:
``` python
########################
# Dall-E로 아웃페인팅
import os
from dotenv import load_dotenv
import openai
load_dotenv()
openai.organization = os.getenv("ORG_ID")
openai.api_key = os.getenv("API_KEY")
outpainted = openai.Image.create_edit(
image=open("outpainting.png", "rb"),
prompt="photo of fashion model",
n=1,
size="1024x1024"
)
```
%% Cell type:code id: tags:
``` python
print(image_url)
```
%% Output
https://oaidalleapiprodscus.blob.core.windows.net/private/org-PRFs4kEWJsQsXXqKKPwiVGFn/user-3PmtWwSkpMcIRxBpjzwzXbZH/img-rg4qRFAuFJaqNSmML2eYwxxA.png?st=2023-05-15T05%3A10%3A06Z&se=2023-05-15T07%3A10%3A06Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2023-05-15T00%3A29%3A49Z&ske=2023-05-16T00%3A29%3A49Z&sks=b&skv=2021-08-06&sig=XQZruKh0rR8q1IxK84Hq2WN6QDiMq8DoSuA//MUjzew%3D
%% Cell type:code id: tags:
``` python
image_url = outpainted.data[0]['url']
response = requests.get(image_url)
image_bytes = response.content
file_path = image_path+"_Dall-E2.png"
download_image(image_url, file_path)
```
%% Output
---------------------------------------------------------------------------
KeyboardInterrupt Traceback (most recent call last)
Cell In[34], line 3
1 image_url = outpainted.data[0]['url']
----> 3 response = requests.get(image_url)
4 image_bytes = response.content
6 file_path = image_path+"_Dall-E2.png"
File ~/.conda/envs/autoImage/lib/python3.10/site-packages/requests/api.py:73, in get(url, params, **kwargs)
62 def get(url, params=None, **kwargs):
63 r"""Sends a GET request.
64
65 :param url: URL for the new :class:`Request` object.
(...)
70 :rtype: requests.Response
71 """
---> 73 return request("get", url, params=params, **kwargs)
File ~/.conda/envs/autoImage/lib/python3.10/site-packages/requests/api.py:59, in request(method, url, **kwargs)
55 # By using the 'with' statement we are sure the session is closed, thus we
56 # avoid leaving sockets open which can trigger a ResourceWarning in some
57 # cases, and look like a memory leak in others.
58 with sessions.Session() as session:
---> 59 return session.request(method=method, url=url, **kwargs)
File ~/.conda/envs/autoImage/lib/python3.10/site-packages/requests/sessions.py:587, in Session.request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
582 send_kwargs = {
583 "timeout": timeout,
584 "allow_redirects": allow_redirects,
585 }
586 send_kwargs.update(settings)
--> 587 resp = self.send(prep, **send_kwargs)
589 return resp
File ~/.conda/envs/autoImage/lib/python3.10/site-packages/requests/sessions.py:745, in Session.send(self, request, **kwargs)
742 pass
744 if not stream:
--> 745 r.content
747 return r
File ~/.conda/envs/autoImage/lib/python3.10/site-packages/requests/models.py:899, in Response.content(self)
897 self._content = None
898 else:
--> 899 self._content = b"".join(self.iter_content(CONTENT_CHUNK_SIZE)) or b""
901 self._content_consumed = True
902 # don't need to release the connection; that's been handled by urllib3
903 # since we exhausted the data.
File ~/.conda/envs/autoImage/lib/python3.10/site-packages/requests/models.py:816, in Response.iter_content.<locals>.generate()
814 if hasattr(self.raw, "stream"):
815 try:
--> 816 yield from self.raw.stream(chunk_size, decode_content=True)
817 except ProtocolError as e:
818 raise ChunkedEncodingError(e)
File ~/.conda/envs/autoImage/lib/python3.10/site-packages/urllib3/response.py:628, in HTTPResponse.stream(self, amt, decode_content)
626 else:
627 while not is_fp_closed(self._fp):
--> 628 data = self.read(amt=amt, decode_content=decode_content)
630 if data:
631 yield data
File ~/.conda/envs/autoImage/lib/python3.10/site-packages/urllib3/response.py:567, in HTTPResponse.read(self, amt, decode_content, cache_content)
564 fp_closed = getattr(self._fp, "closed", False)
566 with self._error_catcher():
--> 567 data = self._fp_read(amt) if not fp_closed else b""
568 if amt is None:
569 flush_decoder = True
File ~/.conda/envs/autoImage/lib/python3.10/site-packages/urllib3/response.py:533, in HTTPResponse._fp_read(self, amt)
530 return buffer.getvalue()
531 else:
532 # StringIO doesn't like amt=None
--> 533 return self._fp.read(amt) if amt is not None else self._fp.read()
File ~/.conda/envs/autoImage/lib/python3.10/http/client.py:465, in HTTPResponse.read(self, amt)
462 if self.length is not None and amt > self.length:
463 # clip the read to the "end of response"
464 amt = self.length
--> 465 s = self.fp.read(amt)
466 if not s and amt:
467 # Ideally, we would raise IncompleteRead if the content-length
468 # wasn't satisfied, but it might break compatibility.
469 self._close_conn()
File ~/.conda/envs/autoImage/lib/python3.10/socket.py:705, in SocketIO.readinto(self, b)
703 while True:
704 try:
--> 705 return self._sock.recv_into(b)
706 except timeout:
707 self._timeout_occurred = True
File ~/.conda/envs/autoImage/lib/python3.10/ssl.py:1274, in SSLSocket.recv_into(self, buffer, nbytes, flags)
1270 if flags != 0:
1271 raise ValueError(
1272 "non-zero flags not allowed in calls to recv_into() on %s" %
1273 self.__class__)
-> 1274 return self.read(nbytes, buffer)
1275 else:
1276 return super().recv_into(buffer, nbytes, flags)
File ~/.conda/envs/autoImage/lib/python3.10/ssl.py:1130, in SSLSocket.read(self, len, buffer)
1128 try:
1129 if buffer is not None:
-> 1130 return self._sslobj.read(len, buffer)
1131 else:
1132 return self._sslobj.read(len)
KeyboardInterrupt:
%% Cell type:code id: tags:
``` python
# 기존 이미지 테두리를 반투명하게 처리
feather = cv2.cvtColor(original, cv2.COLOR_BGR2BGRA)
if original_height >= original_width:
border_size = int(0.05 * original_height)
else:
border_size = int(0.05 * original_width)
for i in range(border_size):
feather[ i,:, 3] = int(255* i/border_size)
feather[-i,:, 3] = int(255* i/border_size)
feather[:, i, 3] = int(255* i/border_size)
feather[:,-i, 3] = int(255* i/border_size)
feather[:border_size , :border_size, 3] = 0
feather[:border_size , -border_size:, 3] = 0
feather[-border_size:, -border_size:, 3] = 0
feather[-border_size:, :border_size, 3] = 0
for radius in range(0, border_size):
for angle in range(0, 90 + 1):
radian = np.deg2rad(angle)
x = int(original.shape[1]- border_size + radius * np.cos(radian))
y = int(original.shape[0]- border_size + radius * np.sin(radian))
feather[y, x][3] = int(255 - 255* radius/border_size)
for angle in range(90, 180 + 1):
radian = np.deg2rad(angle)
x = int(border_size + radius * np.cos(radian))
y = int(original.shape[0]- border_size + radius * np.sin(radian))
feather[y, x][3] = int(255 - 255* radius/border_size)
for angle in range(180, 270 + 1):
radian = np.deg2rad(angle)
x = int(border_size + radius * np.cos(radian))
y = int(border_size + radius * np.sin(radian))
feather[y, x][3] = int(255-255* radius/border_size)
for angle in range(270, 360 + 1):
radian = np.deg2rad(angle)
x = int(original.shape[1] - border_size + radius * np.cos(radian))
y = int(border_size + radius * np.sin(radian))
feather[y, x][3] = int(255 - 255* radius/border_size)
cv2.imwrite('feather.png', feather)
```
%% Output
True
%% Cell type:code id: tags:
``` python
# 아웃 페인팅 위에 기존 이미지 올리기
## 반투명 처리된 이미지 이용
result = cv2.imread(file_path)
new_length = int(1024*longer/ratio)
result = cv2.resize(result, (new_length, new_length))
cv2.imwrite(file_path, result)
x_offset = int((new_length - original_width) / 2)
y_offset = int((new_length - original_height) / 2)
print(x_offset, y_offset, original_width)
subprocess.run(["./magick.appimage","composite", "-geometry", "+" + str(x_offset) + "+" +str(y_offset), "feather.png", file_path, file_path])
```
%% Output
[ WARN:0@2390.271] global loadsave.cpp:244 findDecoder imread_('남자.jpg_Dall-E2.png'): can't open/read file: check file path/integrity
---------------------------------------------------------------------------
error Traceback (most recent call last)
Cell In[36], line 6
4 result = cv2.imread(file_path)
5 new_length = int(1024*longer/ratio)
----> 6 result = cv2.resize(result, (new_length, new_length))
7 cv2.imwrite(file_path, result)
9 x_offset = int((new_length - original_width) / 2)
error: OpenCV(4.7.0) /io/opencv/modules/imgproc/src/resize.cpp:4062: error: (-215:Assertion failed) !ssize.empty() in function 'resize'
%% Cell type:code id: tags:
``` python
#인체가 잘린 경계에서 확장된 부분 삭제
object_move_x = x_offset
object_move_y = y_offset
if object_x == 0:
subprocess.run(["./magick.appimage","convert", file_path, "-gravity", "west", "-chop", (str(x_offset)+"x"+"0"), file_path])
object_move_x = 0
if object_y == 0:
subprocess.run(["./magick.appimage","convert", file_path, "-gravity", "north", "-chop", ("0"+"x"+str(y_offset)), file_path])
object_move_y = 0
if object_x + object_w == original_width:
subprocess.run(["./magick.appimage","convert", file_path, "-gravity", "east", "-chop", (str(x_offset)+"x"+"0"), file_path])
if object_y + object_h == original_height:
subprocess.run(["./magick.appimage","convert", file_path, "-gravity", "south", "-chop", ("0"+"x"+str(y_offset)), file_path])
```
%% Cell type:code id: tags:
``` python
# 객체 탐지
```
%% Cell type:code id: tags:
``` python
# 얼굴 탐지
```
%% Cell type:code id: tags:
``` python
# 확장된 영역의 크기에 따라 제공받은 Oject Detection 결과의 좌표를 이동
```
%% Output
0 310
%% Cell type:code id: tags:
``` python
# 데이터 베이스에 객체(얼굴, 옷) 좌표 저장
```
%% Cell type:code id: tags:
``` python
# 포토샵에 이미지 넣어서 배경 분리
# 사람
# 여백, 머리 포함(T/F), 배경색, 객체만(T/F), 비율,
# 기본값(기본옵션) 설정해야함
# 엑셀 파일로 json request 명세 작성
```
%% Cell type:markdown id: tags:
이미지 경로 / 얼굴 위치 (별도 모델) / 사물 위치 / 상품 정보 1 / 상품 정보 2 / 상품 정보 3 /
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment