728x90

제어문

앞에서 공부한 자료형이 "문자"라면 제어문은 문자를 이용해서 "문장"을 만든다고 생각하시면 될 것 같습니다!

 

IF문

IF문의 구조

if 조건문:
    코드...
else:
    코드...

예를 들어 "배고프면 밥을 먹고 배고프지 않으면 밥을 먹지 않는다."라는 문장이 있을 때 배고프다, 배고프지 않다 라는 조건을 판단하여 결과를 처리해야 하는 경우가 IF문입니다.

 

status="배고프다"
if status=="배고프다":
    print("밥을 먹는다.")
else:
    print("밥을 먹지 않는다.")

# 간단한 코드 설명

# 1. status의 값은 "배고프다"이고

# 2. if status=="배고프다":     => 코드의 의미는 status가 "배고프다"이면

# 3. print("밥을 먹는다.")        => "밥을 먹는다."를 출력한다.

# 4. else:                            => 그렇지 않으면 (배고프다가 아니라면)

# 5. print("밥을 먹지 않는다.") => "밥을 먹지 않는다."를 출력한다.

# 결과: status가 "배고프다" 이므로 "밥을 먹는다."가 출력됩니다.

※주의사항

IF문에 속한 모든 문장에는 아래 #1.와 같이 들여 쓰기를 사용해야 합니다.

만약 #2와 같이 들여 쓰기를 제대로 사용하지 않는 경우 에러가 발생합니다.

JAVA, C 등의 언어를 사용하셨던 분들은 처음에 익숙하지 않을 것 같아요.

(저도 JAVA를 하다가 python을 사용할 때 자주 까먹었던 부분입니다!)

+ 조건문 뒤에 콜론(:)을 붙이는 것도 잊지 마세요! 

#1.
if 조건문:
    코드...
    코드...
#2.
if 조건문:
    코드...
  코드...
    코드...

 

그렇다면 IF 조건문에서 조건문이란?

쉽게 생각해서 참, 거짓을 판단하는 문장을 의미합니다.

example=True
if example:
    print("참!")

example은 True이기 때문에 조건문이 참이 되어 "참!"을 출력하게 됩니다.

 

"3시간 이상 공부했으면 휴식하고, 그렇지 않다면 공부하라"를 출력해보겠습니다.

hour=2
if hour>=3:
    print("휴식하라")
else:
    print("공부하라")

# 간단한 코드 설명

# 1. hour은 2이고

# 2. hour(2)>=3   => 2가 3보다 크거나 같나? False

# 3. 조건문에 만족하지 않기 때문에 "공부하라"를 출력하게 됩니다.

 

and, or, not

x or y   : x 또는 y 중 하나만 True이면 True

x and y : x 와 y 모두 True이면 True

not x    : x가 False이면 True, x가 True이면 False (부정, 반대)

 

or의 예제

"공부를 3시간 이상 했거나, 점수가 100점이라면 휴식하고, 그렇지 않다면 공부하라."를 출력해보겠습니다.

 

hour=2
point=100
if hour>=3 or point==100:
    print("휴식하라")
else:
    print("공부하라")

# 간단한 코드 설명

# 1. hour은 2이고

# 2. point는 100이다.

# 3. hour는 3보다 작아서 False 이지만 point==100 은 True이기 때문에

# 4. "휴식하라"를 출력하게 됩니다.

 

in, not in 예제

나중에 코딩 테스트를 공부하실 때 유용하게 사용되는 부분이니 꼭 알아두시는 것을 추천하겠습니다!

in not in
x in 리스트 x not in 리스트
x in 튜플 x not in 튜플
x in 문자열 x not in 문자열
print(1 in [1,2,3])
print(1 not in [1,2,3])
print('a' in [1,2,3])
print('a' not in 'python')

# 간단한 코드 설명

# 1. 1이 [1,2,3] 리스트 안에 존재하기 때문에 True

# 2. 1이 [1,2,3] 리스트 안에 존재하기 때문에 True이지만 부정이기 때문에 False

# 3. 'a'가 [1,2,3] 리스트 안에 존재하지 않기 때문에 False

# 4. 'a'가 'python' 안에 존재하지 않기 때문에 False이지만 부정이기 때문에 True

 

Quiz) 출력 결과를 예측해보세요!

basket=['apple','banana','orange']
if 'grape' in basket:
    print("있어요!")
else:
    print("없어요!")

정답: 없어요!

 

elif

"공부를 3시간 이상 했으면 휴식하고, 점수가 100점이라면 게임을 하고, 그렇지 않다면 공부하라."를 출력해보겠습니다.

hour=2
point=100

if hour>=3:
    print("휴식하라")
else:
    if point==100:
        print("게임하라")
    else:
        print("공부하라")

if, else만으로는 코드가 복잡하고 지저분해지는데 elif를 사용한다면 이 문제를 해결할 수 있습니다.

hour=2
point=100

if hour>=3:
    print("휴식하라")
elif point==100:
    print("게임하라")
else:
    print("공부하라")

위 코드는 첫 번째 코드와 동일한 코드입니다!

 

# if, elif, else 구조

 

if 조건문:
    코드...
elif 조건문:
    코드...
elif 조건문:
    코드...
...
...
else:
    코드 ...

조건부 표현식

if point >= 80:
    print("잘했어요!")
else:
    print("힘내세요!")

위 코드를 조건부 표현식을 사용하면 아래와 같이 간단하게 표현할 수 있습니다.

print("잘했어요!") if point>=80 else print("힘내세요!")
# 구조
조건이 참일 때의 결과 if 조건문 else 조건문이 거짓일 경우의 결과

조건부 표현식은 가독성이 좋고 코드를 짧게 만들기 때문에 유용하게 사용할 수 있습니다.

728x90

'Python' 카테고리의 다른 글

# 파이썬 - 9 (기초6) for문  (0) 2021.05.22
# 파이썬 - 7 (기초4)  (0) 2021.05.15
# 파이썬 - 6 (기초3)  (0) 2021.05.11
#파이썬 - 5 (기초2)  (3) 2020.07.05
#파이썬 - 4 (기초)  (0) 2020.07.04
728x90

집합 자료형

st1=set([1,2,3])
print(st1)
st2=set("set,study")
print(st2)

집합 자료형은 set을 이용하여 생성할 수 있습니다.

※특징

① 순서가 정해져 있지 않다.

② 중복되지 않는다.

위 st2의 결과를 확인해보면 s와 t가 1개씩만 출력되는 것을 확인하실 수 있습니다!

다양한 집합 구하기

# 합집합
print(st1.union(st2))

# 차집합
print(st1.difference(st2))
print(st2.difference(st1))

# 교집합
st1=set([1,2,3,4,5])
st2=set([3,4,5,6,7])
print(st1.intersection(st2))

결과를 직접 확인해보세요!

집합 자료형 관련 함수

# 값 추가 1개
st1=set([1])
st1.add(2)
print(st1)

# 값 추가 여러개
st1=set([1])
st1.update([2,3])
print(st1)

# 특정 값 제거하기
st1=set([1,2,3])
st1.remove(3)
print(st1)

# add: 값 1개만 추가

# update: 값 여러 개 추가

# remove: 값 삭제

불 자료형

불(boolean)은 True, False를 나타내는 자료형입니다.

a=True
b=False
print(a)
print(b)

불 자료형은 조건문에 많이 사용됩니다. 

# 간단한 조건문
print(1==1)
print(2>1)
print(2<1)

# 1==1: 1과 1은 같나요?  => True

# 2>1: 2가 1보다 큰가요? => True

# 2<1: 2가 1보다 작나요? => False

자료형의 True, False

print(bool("a"))
print(bool(""))
print(bool([1,2]))
print(bool([]))
print(bool(1))
print(bool(0))

정말 간단하게 값이 있다면 True, 비어 있다면 False라고 생각해주세요.

숫자형은 0일 때 False 나머지는 True입니다.

 

복습하기 (드래그로 정답을 확인하세요!)

# 1. 홍길동의 주민등록번호에서 연월일, 뒷자리 수를 나누어 출력

hong="981120-1234567"

# 슬라이싱 사용 yymmdd=hong[:6]

# 슬라이싱 사용 num=[7:]

 

# 2. "2021:05:15" 문자열을 replace 함수를 사용하여 "2021-05-15"로 변환하기

study="2021:05:15"

# study=study.replace(":","-")

 

# 3. 리스트를 이용하여 I Love You 문자열 출력하기

love_list=["I","Love","You"]

# love=" ".join(love_list)

 

# 4. 딕셔너리에서 Key의 Value 출력하기

love_dict={1:"I",2:"Love",3:"You"}
for i in love_dict.keys():
    print(love_dict[i])

출력 결과:

I

Love

You

위와 같은 출력 결과를 만들어보세요!

728x90

'Python' 카테고리의 다른 글

# 파이썬 - 9 (기초6) for문  (0) 2021.05.22
# 파이썬 - 8 (기초5) IF문  (0) 2021.05.19
# 파이썬 - 6 (기초3)  (0) 2021.05.11
#파이썬 - 5 (기초2)  (3) 2020.07.05
#파이썬 - 4 (기초)  (0) 2020.07.04
728x90

기본적인 튜플의 모습

tp=()
tp2=(1)
print(type(tp2))
tp2=(1,)
print(type(tp2))
tp3=(1,2,3)
tp4=(1,2,3,'a',('bc','de'))
tp5=1,2,3
print(type(tp5))

리스트와 비슷한 형태이지만 [] 대괄호로 둘러싸지만 듀플은 () 소괄호로 둘러싸입니다.

리스트는 값을 생성, 삭제, 수정이 가능하지만 튜플은 값을 바꿀 수 없다는 것이 가장 큰 차이점입니다!

또한 위 코드에서 tp2에서 (1) 일 때와 (1,) 일 때의 차이점을 확인해보세요!

(1) 일 때는 int형이고, (1,) 일 때는 tuple인 것을 확인하실 수 있습니다.

즉 튜플은 단 1개의 요소를 가질 때는 요소 뒤에 반드시 콤마(,)를 붙여야 합니다.

tp5 같이 () 소괄호를 생략해도 tp5가 튜플인 것을 확인해보세요!

 

위에서 튜플은 값을 바꿀 수 없다고 했는데 한번 실습을 해서 결과를 확인해보겠습니다!

tp1=(1,2,3)
tp1[0]='a'
#Traceback (most recent call last):
#  File "retry.py", line 2, in <module>
#    tp1[0]='a'
#TypeError: 'tuple' object does not support item assignment

1,2,3으로 구성된 tp1 튜플 객체를 생성하고 tp1의 0번째 요소를 'a'로 바꾸려는 코드입니다.

직접 실행을 해보시면 주석 처리한 에러가 발생할 것입니다!

 

튜플 사용

튜플과 리스트의 차이점은 값을 바꿀 수 없다는 것 빼고는 사용법이 동일하여 간단하게만 사용해보겠습니다.

tp1=('a','b',1,2,3)
print(tp1[0])
print(tp1[0:3])
tp2=('가','나')
print(tp1+tp2)
print(tp1*2)
print(len(tp1))

# tp1[0] : tp1객체(튜플)의 0번째 요소

# tp1[0:3] : tp1객체(튜플)의 0번째부터 2번째 요소까지

# tp1+tp2 : tp1객체(튜플)와 tp2객체(튜플) 요소 합치기

# tp1*2 : tp1객체(튜플)의 요소를 2번 반복 => *2는 곱하기 2와 동일한 의미입니다.

# len(tp1) : tp1객체(튜플)의 길이

Quiz) tp3객체에 tp1객체(튜플)와 tp2객체(튜플)를 합친 후  1,2,3,'가'   를 출력해보세요!

정답: 

tp3=tp1+tp2

print(tp3[2:6])

 

딕셔너리

딕셔너리의 가장 큰 특징은 Key, Value로 구성되어 있다는 것입니다.

ex) 1(Key): 홍길동(Value)   |   2(Key):이순신(Value)   |   3(Key):유관순(Value)

dic1={1:'홍길동',2:'이순신',3:'유관순'}
dic2={'과일':['사과','배','귤'],'동물':['강아지','고양이']}
print(dic1[2])
print(dic2['과일'])

 

# print(dic1[2]) : dic1객체(딕셔너리)에서 Key가 2인 Value를 출력 = 이순신

# print(dic2['과일']) : dic2객체(딕셔너리)에서 Key가 '과일'인 Value를 출력 = ['사과', '배', '귤']

 

딕셔너리 쌍 추가, 삭제

# 추가
dic1={1:'one'}
dic1[2]='two'
print(dic1)
dic1[3]=['three','four']
print(dic1)
# 삭제
del dic1[2]
print(dic1)

딕셔너리 쌍 삭제 방법 : del 객체[요소] 

 

★주의!

딕셔너리의 Key는 변하는 값을 사용할 수 없습니다.

따라서 딕셔너리의 Key에는 리스트를 사용할 수 없습니다. 밑에서 공부하겠지만 딕셔너리도 변하기 때문에 딕셔너리도 Key로 사용할 수 없습니다.

+ 튜플은 변하지 않기 때문에 Key로 사용이 가능합니다.

dic1={[1]:'one'}
#Traceback (most recent call last):
#  File "retry.py", line 11, in <module>
#    dic1={[1]:'one'}
#TypeError: unhashable type: 'list'

dic1={{1:'one'}:'일'}
#Traceback (most recent call last):
#  File "retry.py", line 11, in <module>
#    dic1={{1:'one'}:'일'}
#TypeError: unhashable type: 'dict'

dic1={(1,):'one'}
print(dic1[(1,)])

위 코드를 직접 실행해보세요!

★주의 2!

# Ex1
dic1={1:'one',1:'two'}
print(dic1)

# Ex2
dic1={1:'one',2:'two',3:'four'}
dic1[1]='하나'
print(dic1)

dic1={1:'one',1:'two'} : 초기에 동일한 Key 2개를 생성하면 하나는 무시됩니다.

Ex2에서 1:'one'이 존재하는 상태이고 dic1[1]='하나' 를 입력하면 Key 1의 Value는 '하나'로 변하게 됩니다.

딕셔너리 함수

Key 값 가져오기

dic1={1:'one',2:'two',3:'four'}
print(dic1.keys())

for key in dic1.keys():
    print(key)

Value 값 가져오기

dic1={1:'one',2:'two',3:'four'}
print(dic1.values())

for value in dic1.values():
    print(value)

Key, Value 쌍 가져오기

dic1={1:'one',2:'two',3:'four'}
print(dic1.items())

for key,value in dic1.items():
    print(key," : ",value)

딕셔너리 모든 요소 삭제

dic1={1:'one',2:'two',3:'four'}
dic1.clear()
print(dic1)

Key로 Value값 얻기

dic1={1:'one',2:'two',3:'four'}
print(dic1.get(2))
print(dic1.get('five'))

print(dic1[2])를 했을 때와 print(dic1.get(2))를 했을 때의 결과는 동일합니다.

하지만 print(dic1['five'])는 에러가 발생하지만 print(dic1.get('five'))는 None을 출력하게 됩니다!

차이점: get은 없는 Key값을 찾을 때 None을 return 합니다.

+ 딕셔너리에 Key가 존재하는지 확인

dic1={1:'one',2:'two',3:'four'}
print(1 in dic1)
print(5 in dic1)
728x90

'Python' 카테고리의 다른 글

# 파이썬 - 8 (기초5) IF문  (0) 2021.05.19
# 파이썬 - 7 (기초4)  (0) 2021.05.15
#파이썬 - 5 (기초2)  (3) 2020.07.05
#파이썬 - 4 (기초)  (0) 2020.07.04
#파이썬 - 3 (Visual Studio Code 설정)  (2) 2020.07.02
728x90

프로젝트를 진행하다 보면 엑셀을 이용할 일이 너무 많아서 이번 카테고리를 제작하게 되었습니다.

예를 들어 테이블 정의서, 표준 용어 정리 등등 일일이 Ctrl + F로 찾으려다 보니 너무 힘들더라구용!

 

저희는 앞으로 win32com 라이브러리를 이용해서 업무 자동화를 진행해보겠습니다.

우선 라이브러리가 없으신 분은 pip install pywin32로 설치해주세요!

pip install

Python에서 엑셀을 다뤄보신 분은 대부분 openpyxl을 생각하실 거예요.

프로젝트를 진행하실 때 회사에 설치된 보안 프로그램에 의해서 엑셀 파일이 자동으로 잠기는 경우가 많이 있습니다.

제가 win32com을 사용하는 이유는 openpyxl은 엑셀 파일에 보안이 설정된 경우에는 엑셀 파일을 읽지 못하는 문제가 있기 때문입니다.

import win32com.client as win32

excel=win32.Dispatch("Excel.Application")
test_book=excel.Workbooks.Add()
sheet=test_book.Worksheets("Sheet1")

sheet.Cells(1,1).Value="A1열!"

sheet.Range("A2:B2").Value="범위!"

sheet.Cells(2,2).Interior.ColorIndex = 26
sheet.Cells(2,2).Value="핑크!"

#1. test_book.SaveAs(r'C:\Users\user\Desktop\PythonWorkspace\study.xlsx')
#2. test_book.SaveAs('study.xlsx')

위 코드를 전체 복사 후 붙여 넣기 해주세요.

# 간단한 코드 설명

excel=win32.Dispatch("Excel.Application") # 엑셀 파일을 다룰 수 있는 윈도우 프로그램을 실행합니다.

# 파일 생성

test_book=excel.Workbooks.Add() # 새로운 엑셀 파일 추가합니다.

sheet=test_book.Worksheets("Sheet1") # Sheet1이라는 이름의 워크시트를 생성합니다.

# 셀에 데이터 입력

시트.Cells(행,열) 형태 입니다.
ex) 시트.Cells(1,1) = A1셀   , 시트.Cells(1,2) = B2셀

sheet.Cells(1,1).Value="A1열!" # A1셀에 값 넣기

sheet.Range("A2:B2").Value="범위!" # A2~B2셀에 값 넣기

sheet.Cells(3,1).Interior.ColorIndex = 26 # A3셀에 색상 넣기 (원하는 색상을 넣어보세요!)

sheet.Cells(3,1).Value="핑크!" # A3셀에 값 넣기

색상표

# 저장하기 (경로에 익숙하신 분은 #1로 별도 디렉토리에 저장, 익숙하지 않으신 분은 작업 디렉토리에 저장)

test_book.SaveAs(r'C:\Users\user\Desktop\PythonWorkspace\study.xlsx') # 엑셀 파일 저장하기

 

# 결과 확인

study.xlsx
결과 엑셀

1편은 간단하게 기본만 확인하고 다음장에는 실무에 유용한 엑셀 다루는 방법을 알아보겠습니다!

728x90
728x90

이번에는 썸네일을 자동으로 생성해주는 카카오톡 비전 API를 공부해보겠습니다.

카카오톡 비전에서 제공하는 썸네일은 이미지 내의 콘텐츠를 바탕으로 중요한 부분을 썸네일로 생성해주는 API입니다. 요청한 width, height 비율에 따라 이미지를 잘라내어 반환합니다.

필요한 이미지 첨부합니다!

fox.jpg
0.29MB
Hedgehog.jpg
0.29MB
maltese.jpg
0.55MB
pug.jpg
0.54MB

1. REST API

앱키

REST API키를 복사해주세요.

 

2. 테스트 python 코드

import sys
import argparse
import requests
from PIL import Image, ImageFilter

API_URL = 'https://dapi.kakao.com/v2/vision/thumbnail/detect'
MYAPP_KEY = '위 1에서 복사한 RESTAPI키'

def detect_thumbnail(filename, width, height):
    headers = {'Authorization': 'KakaoAK {}'.format(MYAPP_KEY)}

    try:
        files = { 'image' : open(filename, 'rb')}
        params = {'width': width, 'height': height}
        resp = requests.post(API_URL, headers=headers, data=params, files=files)
        resp.status_code
        #print(resp.json())
        return resp.json()
    except Exception as e:
        print(str(e))
        sys.exit(0)

def show_thumbnail(filename, detection_result, width, height):
    image = Image.open(filename)
    rect = detection_result['result']['thumbnail']
    thumbnail = image.crop((rect['x'], rect['y'], rect['x'] + rect['width'], rect['y'] + rect['height']))
    thumbnail = thumbnail.resize((width, height))

    return thumbnail


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='썸네일')
    #1.parser.add_argument('image_file', type=str, nargs='?', default="./kakao_test/Hedgehog.jpg", help='썸네일 이미지 만들기')
    #2.parser.add_argument('image_file', type=str, nargs='?', default="./Hedgehog.jpg", help='썸네일 이미지 만들기')
    parser.add_argument('width', type=int, nargs='?', default=150, help='넓이')
    parser.add_argument('height', type=int, nargs='?', default=200, help='높이')

    args = parser.parse_args()

    detection_result = detect_thumbnail(args.image_file, args.width, args.height)
    image = show_thumbnail(args.image_file, detection_result, args.width, args.height)
    image.show()

※ 간단한 코드 설명

경로에 익숙하신 분은 #1로 별도의 디렉토리로, 익숙하지 않으신분은 #2를 이용해주세요!

이번에는 아래의 새로운 코드가 추가 되었습니다.

parser.add_argument('width', type=int, nargs='?', default=150, help='넓이') # 사진의 기본 넓이를 150으로 조정

parser.add_argument('height', type=int, nargs='?', default=200, help='높이') # 사진의 기본 크기를 200으로 조정

썸네일을 만들 사진의 크기를 조정하는 코드라고 생각하시면 될 것 같습니다.

 

* detect_product 함수

detect_product함수에 해당 이미지 파일, 넓이, 높이 3개의 인자를 보내줍니다.

files = { 'image' : open(filename, 'rb')} # 'image'(Key):이미지파일(value)형태의 딕셔너리를 files에 저장합니다.

params = {'width': width, 'height': height} # 'width'(Key):넓이(value), 'height'(Key):높이(value)형태의 딕셔너리를 params에 저장합니다.

resp = requests.post(API_URL, headers=headers, data=params, files=files) # URL에 요청하는 코드

필요한 파라미터는 다음과 같습니다.

파라미터

좀 더 자세히 확인하고 싶으신 분은 아래 주소나 이미지를 클릭하신 후 Ctrl+F를 누르신 후 썸네일을 검색해보세요!

developers.kakao.com/docs/latest/ko/vision/dev-guide#create-thumbnail

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

#print(resp.json()) 부분의 주석을 풀면 json객체를 확인해보실 수 있습니다.

 

* show_thumbnail함수

이미지 사이즈를 조정해주는 함수입니다.

thumbnail = image.crop((rect['x'], rect['y'], rect['x'] + rect['width'], rect['y'] + rect['height'])) # 해당 사이즈로 이미지를 자르고

thumbnail = thumbnail.resize((width, height)) # 이미지 사이즈를 다시 조정합니다.

3. 결과 이미지(Before & After)

01

4. 이미지 저장 코드

import sys
import argparse
import requests
from PIL import Image, ImageFilter
import os
import glob

API_URL = 'https://dapi.kakao.com/v2/vision/thumbnail/detect'
MYAPP_KEY = '위 1에서 복사한 RESTAPI키'

def detect_thumbnail(filename, width, height):
    headers = {'Authorization': 'KakaoAK {}'.format(MYAPP_KEY)}

    try:
        files = { 'image' : open(filename, 'rb')}
        params = {'width': width, 'height': height}
        resp = requests.post(API_URL, headers=headers, data=params, files=files)
        resp.status_code
        #print(resp.json())
        return resp.json()
    except Exception as e:
        print(str(e))
        sys.exit(0)

def show_thumbnail(filename, detection_result, width, height):
    image = Image.open(filename)
    rect = detection_result['result']['thumbnail']
    thumbnail = image.crop((rect['x'], rect['y'], rect['x'] + rect['width'], rect['y'] + rect['height']))
    thumbnail = thumbnail.resize((width, height))

    return thumbnail


if __name__ == "__main__":

    files=glob.glob('./kakao_test/thumbnail/*.jpg')+glob.glob('./kakao_test/thumbnail/*.jpeg')+glob.glob('./kakao_test/thumbnail/*.png')
    width=150
    height=200

    for i in files:
        head,tail = os.path.split(i)
        detection_result = detect_thumbnail(i,width,height)
        image = show_thumbnail(i, detection_result, width, height)
        image.save(head+'/thumbnail_'+tail,'JPEG')

files객체를 생성하실 때 경로에 익숙하신 분은 #1. 번에서 별도의 이미지 디렉토리를 이용하시고 익숙하지 않으신 분은 #2. 번익숙하지 않으신 분은 python 코드를 작업하는 디렉토리에 이미지를 넣어주시고 #2. 번을 사용해주세요. 둘 중 하나만 사용하셔야 합니다!

 

5. 결과 이미지

0123
썸네일

728x90
728x90

2장 카카오톡 상품 검출 API는 이미지 콘텐츠를 분석해서 상품들의 위치와 종류를 검출합니다.

필요한 이미지 첨부합니다!

shop.jpg
0.48MB
shop2.jpg
0.33MB
shop3.jpg
0.51MB
shop4.jpg
0.40MB

추가적으로 얼굴 이미지를 구하실 분들은 아래 링크에서 이미지를 다운로드하세요!

저작권이 없는 이미지 사이트입니다. --> pixabay.com/

1. REST API

앱키

REST API 키를 복사해주세요.

2. 테스트 python 코드

import sys
import argparse
import requests
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO

API_URL = 'https://dapi.kakao.com/v2/vision/product/detect'
MYAPP_KEY = '위 1에서 복사한 RESTAPI키'

def detect_product(filename):
    headers = {'Authorization': 'KakaoAK {}'.format(MYAPP_KEY)}
    try:
        files = { 'image' : open(filename, 'rb')}
        resp = requests.post(API_URL, headers=headers, files=files)
        resp.status_code
        #print(resp.json())
        return resp.json()
    except Exception as e:
        print(str(e))
        sys.exit(0)

def show_products(filename, detection_result):
    try:
        image = Image.open(filename)
    except Exception as e:
        print(str(e))
        sys.exit(0)
    draw = ImageDraw.Draw(image)
    for obj in detection_result['result']['objects']:
        x1 = int(obj['x1']*image.width)
        y1 = int(obj['y1']*image.height)
        x2 = int(obj['x2']*image.width)
        y2 = int(obj['y2']*image.height)
        draw.rectangle([(x1,y1), (x2, y2)], fill=None, outline=(255,0,0,255))
        draw.text((x1+5,y1+5), obj['class'], (255,0,0))
    del draw
    return image

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='상품 인식')
    #1.parser.add_argument('image_file', type=str, nargs='?',default="./kakao_test/Image/shop4.jpg",help='image url to show product\'s rect')
    #2.parser.add_argument('image_file', type=str, nargs='?',default="./shop4.jpg",help='image url to show product\'s rect')
    args = parser.parse_args()
    detection_result = detect_product(args.image_file)
    image = show_products(args.image_file, detection_result)
    image.show()

※ 간단한 코드 설명

parser 부분인 얼굴 검출 편에서 설명했으므로 건너가도록 하겠습니다.

경로에 익숙하신 분은 #1.처럼 별도의 이미지 디렉토리를 생성하셔서 경로를 주시면 되고 익숙하지 않으신 분은 python 코드를 작업하는 디렉토리에 이미지를 넣어주시고 #2. 번을 사용해주세요. 둘 중 하나만 사용하셔야 합니다!

* detect_product 함수

기존 코드는 얼굴 검출편과 동일하고 요청에 성공하면 응답은 JSON 객체로 검출된 상품 영역 정보를 받게 됩니다.

#print(resp.json()) 주석 처리된 부분을 해제하시고 어떻게 출력되는지 확인해보세요.

얼굴 검출편과는 다르게 상품의 정보가 나오게 됩니다.

아래와 같이 딕셔너리에서 class부분을 살펴보시면 상품이 무엇인지를 확인할 수 있습니다.

{'width': 1394, 'objects': [{'y2': 0.998958, 'x2': 0.66858, 'score': 0.994, 'y1': 0.746875, 'x1': 0.243902, 'class': 'pants'}

* show_products 함수

이미지 파일을 읽어서 상품이 있는 위치에 박스와 이름을 만들어주는 함수입니다.

draw.rectangle([(x1, y1), (x2, y2)], fill=None, outline=(255,0,0,255)) # 빨간색으로 박스를 만들고

draw.text((x1+5,y1+5), obj['class'], (255,0,0)) # 빨간색으로 상품 이름을 적어줍니다.

3. 결과 이미지

결과 이미지

4. 이미지 저장 코드

import sys
import argparse
import requests
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
import glob
import os

API_URL = 'https://dapi.kakao.com/v2/vision/product/detect'
MYAPP_KEY = '위 1에서 복사한 RESTAPI키'

def detect_product(filename):
    headers = {'Authorization': 'KakaoAK {}'.format(MYAPP_KEY)}
    try:
        files = { 'image' : open(filename, 'rb')}
        resp = requests.post(API_URL, headers=headers, files=files)
        resp.status_code
        #print(resp.json())
        return resp.json()
    except Exception as e:
        print(str(e))
        sys.exit(0)

def show_products(filename, detection_result):
    try:
        image = Image.open(filename)
    except Exception as e:
        print(str(e))
        sys.exit(0)
    draw = ImageDraw.Draw(image)
    for obj in detection_result['result']['objects']:
        x1 = int(obj['x1']*image.width)
        y1 = int(obj['y1']*image.height)
        x2 = int(obj['x2']*image.width)
        y2 = int(obj['y2']*image.height)
        draw.rectangle([(x1,y1), (x2, y2)], fill=None, outline=(255,0,0,255))
        draw.text((x1+5,y1+5), obj['class'], (255,0,0))
    del draw
    return image

if __name__ == "__main__":

    #1.files=glob.glob('./kakao_test/Image/*.jpg')+glob.glob('./kakao_test/Image/*.jpeg')+glob.glob('./kakao_test/Image/*.png')
    #2.files=glob.glob('./*.jpg')+glob.glob('./*.jpeg')+glob.glob('./*.png')
    for i in files:
        head,tail = os.path.split(i)
        detection_result = detect_product(i)
        image = show_products(i, detection_result)
        image.save(head+'/product_'+tail,'JPEG')

files객체를 생성하실 때 경로에 익숙하신 분은 #1. 번에서 별도의 이미지 디렉토리를 이용하시고 익숙하지 않으신 분은 #2. 번익숙하지 않으신 분은 python 코드를 작업하는 디렉토리에 이미지를 넣어주시고 #2. 번을 사용해주세요. 둘 중 하나만 사용하셔야 합니다!

이후 코드는 1-2. 얼굴 검출[저장편]과 동일하기 때문에 생략하겠습니다!

 

5. 결과 이미지

0123
결과 이미지

얼굴 검출편과 코드가 대부분 동일해서 설명을 간략하게 하고 넘어갔는데 혹시라도 이해가 안가시는 부분이 있으시다면 댓글에 남겨주세요.

모르시는 부분을 댓글에 남겨주시는 것은 다른 분들에게도 도움이 됩니다. 도와주세용~!

 

 

 

 

 

728x90
728x90

이번에는 여러 장의 사진을 이용하여 모자이크 후 이미지 파일을 저장하는 방법을 설명하도록 하겠습니다.

필요한 이미지 다시 한번 첨부드립니다!

cat.jpg
0.33MB
girl1.jpg
0.38MB
girl2.jpg
0.81MB
gorilla.jpg
0.51MB
lion.jpg
0.38MB

추가적으로 얼굴 이미지를 구하실 분들은 아래 링크에서 face를 입력 후 다운로드하세요!

저작권이 없는 이미지 사이트입니다. --> pixabay.com/

1. REST API

앱키

REST API키를 복사해주세요.

 

2. python 코드

import sys
import argparse
import requests
from PIL import Image, ImageFilter
import glob
import os

API_URL = 'https://dapi.kakao.com/v2/vision/face/detect'
RESTAPI_KEY = '위 1에서 복사한 RESTAPI키'

def detect_face(filename):
    headers = {'Authorization': 'KakaoAK {}'.format(RESTAPI_KEY)}

    try:
        files = { 'image' : open(filename, 'rb')}
        resp = requests.post(API_URL, headers=headers, files=files)
        resp.status_code
        return resp.json()
    except Exception as e:
        print(str(e))
        sys.exit(0)

def mosaic(filename, detection_result):
    image = Image.open(filename)

    for face in detection_result['result']['faces']:
        x = int(face['x']*image.width)
        w = int(face['w']*image.width)
        y = int(face['y']*image.height)
        h = int(face['h']*image.height)
        box = image.crop((x,y,x+w, y+h))
        box = box.resize((20,20), Image.NEAREST).resize((w,h), Image.NEAREST)
        image.paste(box, (x,y,x+w, y+h))

    return image



if __name__ == "__main__":

    #1.files=glob.glob('./kakao_test/*.jpg')+glob.glob('./kakao_test/*.jpeg')+glob.glob('./kakao_test/*.png')
    #2.files=glob.glob('./*.jpg')+glob.glob('./*.jpeg')+glob.glob('./*.png')
    
    for i in files:
        head,tail = os.path.split(i)
        detection_result = detect_face(i)
        image = mosaic(i, detection_result)
        image.save(head+'/Mosaic_'+tail,'JPEG')

※ 간단한 코드 설명! (이전 코드와 다른 점만 간단하게 설명하겠습니다.)

files 부분에서 경로에 익숙하신 분은 #1에서 별도의 이미지 디렉토리를 만들어서 이미지들을 저장하시고 경로를 맞춰주세요. 익숙하지 않으신 분은 python코드가 돌아가는 디렉토리에 이미지를 저장해주세요.

files부분에서 #1과 #2 둘중 하나만 사용하셔야 합니다!

glob라이브러리를 이용하여 "kakao_test" 디렉토리 밑에 있는 .jpg, .jpeg, .png의 이미지 파일들의 경로를 리스트로 만들어 files라는 객체를 생성합니다.

for 문을 이용하여 files 객체에 담은 이미지 파일 경로 요소들을 하나씩 꺼냅니다.

head,tail = os.path.split(i) # os 라이브러리를 이용하여 head 객체에는 이미지 파일이 들어있는 디렉토리 경로, tail객체에는 이미지 파일명을 생성합니다.

detection_result = detect_face(i) # 이전 코드와 동일하게 얼굴 정보에 대한 json파일을 return 받습니다.

image = mosaic(i, detection_result) # 이전 코드와 동일합니다. (모자이크하는 함수)

image.save(head+'/Mosaic_'+tail, 'JPEG') # image.save를 이용하여 jpeg라는 이미지 파일을 디렉토리 경로+/Mosaic_이미지 파일명으로 생성합니다.

#1. 코드를 사용한다면 "./kakao_test/Mosaic_cat.jpg"라는 이미지 파일이 생성되게 됩니다!

 

3. 결과 확인

위 예제 코드를 성공하셨다면 결과를 확인해보세요.

흥미로운 점은 사람뿐만 아니라 사자, 고릴라, 고양이 모두 얼굴에 모자이크가 되어있는 것을 확인하실 수 있습니다.

추가적으로 최상단에 있는 링크에서 여러 이미지를 다운로드 후 새로운 이미지들을 제작해보세요!

01234
결과 이미지

 

728x90
728x90

안녕하세요! 

카카오톡 api를 공부하시는 분들이 많으신 것 같아서 이번에는 재밌고 신기한 비전을 사용해 보려고 합니다.

카카오톡 비전에는 얼굴 검출, 상품 검출, 성인 이미지 판별 등이 있습니다.

1편에는 얼굴 검출을 사용해 보겠습니다.

필요한 이미지 첨부해드릴게요!

cat.jpg
0.33MB
girl1.jpg
0.38MB
girl2.jpg
0.81MB
gorilla.jpg
0.51MB
lion.jpg
0.38MB

추가적으로 얼굴 이미지를 구하실 분들은 아래 링크에서 face를 입력 후 다운로드하세요!

저작권이 없는 이미지 사이트입니다. --> pixabay.com/

1. REST API

앱 키

메시지 보내기 편에서 사용한 REST API키를 복사해주세요.

위 이미지를 모르시는 분은 메시지 보내기 편을 먼저 사용해보세요!

novice-engineers.tistory.com/9?category=908185

 

[Python] 10분 만에 카카오톡 메시지 보내기 - (1. 사용자 토큰 발급)

1. Kakao Developers 사이트 이동 www.developers.kakao.com/ Kakao Developers 카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합..

novice-engineers.tistory.com

2. python 코드

얼굴을 검출하여 모자이크 하는 코드입니다.

import sys
import argparse
import requests
from PIL import Image, ImageFilter

API_URL = 'https://dapi.kakao.com/v2/vision/face/detect'
RESTAPI_KEY = '1에서 복사한 REST API키'

def detect_face(filename):
    headers = {'Authorization': 'KakaoAK {}'.format(RESTAPI_KEY)}

    try:
        files = { 'image' : open(filename, 'rb')}
        resp = requests.post(API_URL, headers=headers, files=files)
        resp.resp.status_code
        #print(resp.json())
        return resp.json()
    except Exception as e:
        print(str(e))
        sys.exit(0)

def mosaic(filename, detection_result):
    image = Image.open(filename)

    for face in detection_result['result']['faces']:
        x = int(face['x']*image.width)
        w = int(face['w']*image.width)
        y = int(face['y']*image.height)
        h = int(face['h']*image.height)
        box = image.crop((x,y,x+w, y+h))
        box = box.resize((20,20), Image.NEAREST).resize((w,h), Image.NEAREST)
        image.paste(box, (x,y,x+w, y+h))

    return image



if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='얼굴 모자이크.')
    # 1.parser.add_argument('image_file', type=str, nargs='?', default="./kakao_test/girl1.jpg", help='image file to hide faces')
    # 2.parser.add_argument('image_file', type=str, nargs='?', default="./girl1.jpg", help='image file to hide faces')

    args = parser.parse_args()

    detection_result = detect_face(args.image_file)
    image = mosaic(args.image_file, detection_result)
    image.show()

※ 간단한 코드설명!

앞으로도 코드가 매우 비슷하기 때문에 얼굴 검출편에서 정확하게 이해하시는게 중요합니다!

우선 RESTAPI_KEY에 1에서 복사한 REST API 키를 복사해서 넣어주세요.

argparse란 프로그램에 필요한 인자를 사용자 명령행 인터페이스로 쉽게 작성하도록 도와주는 라이브러리입니다.

command 창에서 프로그램 내의 인자를 조절할 수 있도록 도와줍니다. 기본적으로 python에 내장되어 있습니다.

==> 사용자가 편리하게 사용할 수 있도록 도와주는 라이브러리라고 생각하시면 될 것 같아용!

parser = argparse.ArgumentParser(description='얼굴 모자이크') # 설명을 기입하는 코드라고 생각하세요.

parser.add_argument('image_file', type=str, nargs='?', default="./kakao_test/girl1.jpg", help='image file to hide faces')

위 코드에서 "./kakao_test/girl1.jpg" 해당 경로의 girl1.jpg라는 이미지를 사용한다고 생각해주세요!

★ 경로에 익숙하신 분은 #1번을 이용하여 자신만의 이미지 디렉토리 경로에 넣어주시고 익숙하지 않으신 분은 작업 디렉토리에 이미지를 다운로드하시고 #2번을 이용해주세요. 둘 중 하나만 사용하셔야 합니다!

 

* detect_face함수 설명

headers = {'Authorization': 'KakaoAK {}'.format(RESTAPI_KEY)} # 이번에는 헤더가 메시지편과 조금 다릅니다.

이유가 궁금하신 분은 아래 추가 설명을 확인해보세요. (사실 중요한 부분은 아닙니다. 급하신 분은 넘어가셔두 돼용 ㅎ)

 

<추가 설명>

1. 아래 링크나 이미지를 클릭하셔서 사이트로 이동합니다.

developers.kakao.com/docs/latest/ko/vision/dev-guide#recog-face

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

2. Ctrl+F를 누르시고 Request를 입력하세요.

3. URL부분에 있는 Authorization을 확인하시면 KakaoAk {REST_API_KEY}로 되어 있습니다.

Authorization

 

files = { 'image' : open(filename, 'rb')} # 'image':파일 라는 Key, Value인 딕셔너리 형태로 만들어 줍니다.

resp = requests.post(API_URL, headers=headers, files=files) #해당 형태로 보내줍니다.

resp.status_code # 정상적으로 보내졌는지 확인

return resp.json() # 이 부분이 중요합니다!

 

요청에 성공하면 응답은 JSON 객체로 검출된 얼굴 영역 정보를 받게 됩니다.

#print(resp.json()) 주석 처리된 부분을 해제하시고 어떻게 출력되는지 확인해보세요.

얼굴의 정보들을 확인할 수 있습니다. 흥미로운 부분은 성별, 나이 등을 추측한 %를 확인하실 수 있어요.

 

* mosaic함수: 모자이크를 처리해주는 함수입니다.

모자이크 강도를 조절하실 분은

box = box.resize((20,20), Image.NEAREST).resize((w,h), Image.NEAREST) # 이 코드에서 숫자를 변경해보세요!

 

3. 실행

# 초기 이미지

 

# 결과 이미지

다음 편에서는 여러 장의 이미지들을 한 번에 모자이크하는 코드를 확인해보겠습니다.

(사실 한번에 하려고 했는데 분량 조절에 실패했습니당ㅎ...)

 

728x90
728x90

이전 2장에서 혹시라도 안되시는 분들을 위해 추가적으로 셋팅을 올리겠습니다.

1. 본인인증 확인

01
본인 인증 확인

1. 우측 상단에 자신의 아이디를 클릭

2. 계정 설정 클릭

3. 스크롤을 내린 후 본인인증이 되어 있는지 확인

 

2. 동의 항목

01234

1. 메인에서 내 애플리케이션 클릭

2. 자신이 만든 app 클릭

3. 좌측의 동의항목 클릭

4. 프로필 정보 동의

5. 스크롤 내린 후 카카오톡 메시지 전송 동의

 

감사합니다.

728x90
728x90

사용자 토큰을 발급받지 않으신 분은 반드시 1편을 수행해주세요!

www.novice-engineers.tistory.com/9?category=908185

 

[Python] 10분 만에 카카오 오픈 API로 메시지 보내기 - (1. 사용자 토큰 발급)

1. Kakao Developers 사이트 이동 www.developers.kakao.com/ Kakao Developers 카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합..

novice-engineers.tistory.com

1. 메시지 이동

012

위 슬라이드 쇼를 참고해주세요.

1. 문서 클릭

2. 스크롤을 조금 내린 후 [메시지 박스 안에 있는 REST API 클릭]

3. [Ctrl + F]를 누른 후 Request를 입력

4. URL이란 박스 안에 아래와 같은 코드를 확인하실 수 있습니다.

POST/v2/api/talk/memo/default/send HTTP/1.1
Host: kapi.kakao.com
Authorization: Bearer {ACCESS_TOKEN}

=> https://kapi.kakao.com/v2/api/talk/memo/default/send 이러한 주소가 됩니다.

 

2. Visual Studio Code에 코드 입력 & 실행

import requests
import json

#1.
with open(r"C:\Users\user\Desktop\PythonWorkspace\kakao_test\kakao_code.json","r") as fp:
    tokens = json.load(fp)

#2.
with open("kakao_code.json","r") as fp:
    tokens = json.load(fp)

url="https://kapi.kakao.com/v2/api/talk/memo/default/send"

# kapi.kakao.com/v2/api/talk/memo/default/send 

headers={
    "Authorization" : "Bearer " + tokens["access_token"]
}

data={
    "template_object": json.dumps({
        "object_type":"text",
        "text":"Hello, world!",
        "link":{
            "web_url":"www.naver.com"
        }
    })
}

response = requests.post(url, headers=headers, data=data)
response.status_code

이전 1강에서 사용한 with open에 따라 #1. 또는 #2. 중 하나만 선택하여 사용하시면 됩니다.

(오류 나시는 분들은 하단에 에러들 참고해서 코드를 수정해보세요!)

 

실행 후 자신의 카카오톡을 확인해주세요!

이렇게 메시지가 온 것을 확인하실 수 있습니다.

 

 

 

 

 

 

※ 간략한 코드 설명

headers={
"Authorization" : "Bearer " + tokens["access_token"]
}
# "Bearer"이라는 문자열과 json에서 불러온 access_token의 value를 조합하여 인증키를 만든다.

 

data={
"template_object": json.dumps({
"object_type":"text",
"text":"Hello, world!",
"link":{
"web_url":"www.naver.com"
}
})
}

# object_type은 text 고정값
# text에는 내용
# link는 필수사항이라서 그냥 네이버를 넣어줬습니다.

아래 링크를 참조하시면 이해하시는데 도움될 것 같습니다!

www.developers.kakao.com/docs/latest/ko/message/message-template#text

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

 

response = requests.post(url, headers=headers, data=data)
response.status_code

# 위 2줄의 코드가 메시지를 보내는 과정입니다.

 

※ 추가 (scop error)

print(response.status_code)
if response.json().get('result_code') == 0:
	print('메시지를 성공적으로 보냈습니다.')
else:
	print('메시지를 성공적으로 보내지 못했습니다. 오류메시지 : ' + str(response.json()))

 

위에서 scop error 나시는 분은 어플리케이션 생성 하실때 동의 항목에서 설정하시고 토큰 받으시면 됩니다.

공유해 주신 김대성님 정말 감사합니다! :)

 

※ 추가 (403 error)

메시지를 성공적으로 보내지 못했습니다. 오류메시지 : {'msg': 'insufficient scopes.', 'code': -402, 'api_type': 'TALK_MEMO_DEFAULT_SEND', 'required_scopes': ['talk_message'], 'allowed_scopes': ['profile_nickname']}

'3. 동의항목'을 참고로해도 동일 메시지를 받아서 하단 코드를

https://kauth.kakao.com/oauth/authorize?client_id={client_id}&redirect_uri=https://example.com/oauth&response_type=code

아래와 같이 수정하니 추가 동의하고 성공했습니다.

https://kauth.kakao.com/oauth/authorize?client_id={client_id}&redirect_uri=https://example.com/oauth&response_type=code&scope=profile_nickname,friends,talk_message

※ 추가 (401 error)

headers={
'Authorization': 'Bearer' + tokens['access_token']
}
상단의 코드를 아래와 같이 수정
headers={
'Authorization': 'Bearer' + ' ' + tokens['access_token']
}

오류 및 해결 방법을 공유해 주신 분들 정말로 감사드립니다!

728x90

+ Recent posts