오늘은 어제에 이어서 Pillow라는 라이브러리를 이용해서 OpenCV에 한글을 그리는 방법부터 블러, 이진화 등 약간 이론적으로 이해가 필요한 내용이 있었지만 크게 어려운 내용은 없었다. 오늘부터 어려운 내용들이 시작된다고 했는데 아직까지는 할 만한 것 같다.
pip install pillow 사용from PIL import Image, ImageDraw, ImageFont
img = np.zeros((460, 640, 3), dtype=np.uint8)
def putKorText(img, text, position, font_size, font_color):
img_pil = Image.fromarray(img)
draw = ImageDraw.Draw(img_pil)
font = ImageFont.truetype("/System/Library/Fonts/AppleSDGothicNeo.ttc", font_size)
draw.text(position, text, font=font, fill=font_color)
return np.array(img_pil)
text = putKorText(img, "안녕하세요", (220,300), 30, (255,255,255))
cv.imshow("KOR", text)
cv.waitKey(0)
cv.destroyAllWindows()
cv.waitKey(1)
cv2.blur(img, kernel) : 단순 평균 방식cv2.GaussianBlur(img, kernel, 표준편차) : 가우시안 평균 방식cv2.medianBlur(img, kernel) : 중앙값 사용 방식img = cv.imread(DOG_PATH)
# 평균 블러
blur_avg = cv.blur(img, (5,5))
# 가우시안 블러
blur_gaussian = cv.GaussianBlur(img, (5,5), 0)
cv.imshow("Blur", blur_avg)
cv.imshow("Gaussian", blur_gaussian)
cv.waitKey(0)
cv.destroyAllWindows()
cv.waitKey(1)
img = cv.imread(DOG_PATH)
kernel_3 = cv.GaussianBlur(img, (3,3), 0)
kernel_5 = cv.GaussianBlur(img, (5,5), 0)
kernel_7 = cv.GaussianBlur(img, (7,7), 0)
cv.imshow("kernel_3", kernel_3)
cv.imshow("kernel_5", kernel_5)
cv.imshow("kernel_7", kernel_7)
cv.waitKey(0)
cv.destroyAllWindows()
cv.waitKey(1)
img = cv.imread(DOG_PATH)
sigma_1 = cv.GaussianBlur(img, (0,0), 1)
sigma_2 = cv.GaussianBlur(img, (0,0), 2)
sigma_3 = cv.GaussianBlur(img, (0,0), 3)
cv.imshow("sigma_1", sigma_1)
cv.imshow("sigma_2", sigma_2)
cv.imshow("sigma_3", sigma_3)
cv.waitKey(0)
cv.destroyAllWindows()
cv.waitKey(1)
cv2.threshold(img, threshold, maxValue, type)img = cv.imread(BOOK_PATH, cv.IMREAD_GRAYSCALE)
ret, binary = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
cv.imshow("img", img)
cv.imshow("binary", binary)
cv.waitKey(0)
cv.destroyAllWindows()
cv.waitKey(1)
cv2.createTrackbar(trackbarName, name, startValue, maxValue, callback) : 트랙바 생성cv2.getTrackbarPos(trackbarName, name) : 트랙바의 값을 가져옴img = cv.imread(BOOK_PATH, cv.IMREAD_GRAYSCALE)
# 트랙바 생성 이전에 창이 만들어져 있어야함
name = "Threshold"
cv.namedWindow(name)
# 콜백 함수는 필수
def trackbar_func(x):
pass
# 트랙바 생성
trackbar_name = "threshold"
cv.createTrackbar(trackbar_name, name, 127, 255, trackbar_func)
while True:
threshold = cv.getTrackbarPos(trackbar_name, name)
ret, binary = cv.threshold(img, threshold, 255, cv.THRESH_BINARY)
cv.imshow("name", binary)
if cv.waitKey(1) == ord("q"):
break
cv.destroyAllWindows()
cv.waitKey(1)
img = cv.imread(DOG_PATH)
name = "Resize"
cv.namedWindow(name)
trackbar_name = "scale(%)"
cv.createTrackbar(trackbar_name, name, 100, 200, lambda x:x)
while True:
scale = cv.getTrackbarPos(trackbar_name, name)
if scale == 0:
scale = 1
width = int(img.shape[1] * scale / 100)
height = int(img.shape[0] * scale / 100)
resized = cv.resize(img, (width, height))
cv.imshow(name, resized)
if cv.waitKey(1) == ord("q"):
break
cv.destroyAllWindows()
cv.waitKey(1)
img = np.zeros((460, 640, 3), dtype=np.uint8)
name = "COLOR"
cv.namedWindow(name)
cv.createTrackbar("B", name, 0, 255, lambda x:x)
cv.createTrackbar("G", name, 0, 255, lambda x:x)
cv.createTrackbar("R", name, 0, 255, lambda x:x)
trackbar_name = "0:OFF\n1:ON"
cv.createTrackbar(trackbar_name, name, 1, 1, lambda x:x)
while True:
B = cv.getTrackbarPos("B", name)
G = cv.getTrackbarPos("G", name)
R = cv.getTrackbarPos("R", name)
switch = cv.getTrackbarPos(trackbar_name, name)
if switch == 1:
img[:] = (B,G,R)
cv.imshow(name, img)
if cv.waitKey(1) == ord("q"):
break
cv.destroyAllWindows()
cv.waitKey(1)
cv2.adaptiveThreshold(img, maxValue, adaptiveMethod, thresholdType, blockSize, C)img = cv.imread(BOOK_PATH, cv.IMREAD_GRAYSCALE)
name = "Adaptive Threshold"
cv.namedWindow(name)
cv.createTrackbar("block_size", name, 25, 100, lambda x:x)
cv.createTrackbar("C", name, 1, 10, lambda x:x)
while True:
block_size = cv.getTrackbarPos("block_size", name)
C = cv.getTrackbarPos("C", name)
if block_size <= 1:
block_size = 3
if block_size % 2 == 0:
block_size += 1
binary = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, block_size, C)
cv.imshow(name, binary)
if cv.waitKey(1) == ord("q"):
break
cv.destroyAllWindows()
cv.waitKey(1)
img = cv.imread(DOG_PATH, cv.IMREAD_GRAYSCALE)
ret_1, binary = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
ret_2, otsu = cv.threshold(img, -1, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
print(ret_1, ret_2)
cv.imshow("img", binary)
cv.imshow("otsu", otsu)
cv.waitKey(0)
cv.destroyAllWindows()
cv.waitKey(1)
rotateCodecv2.ROTATE_90_CLOCKWISE : 시계방향 90도 회전cv2.ROTATE_180 : 180도 회전cv2.ROTATE_90_COUNTERCLOCKWISE : 반시계방향 90도 회전img = cv.imread(DOG_PATH)
dst_90 = cv.rotate(img, cv.ROTATE_90_CLOCKWISE)
dst_180 = cv.rotate(img, cv.ROTATE_180)
dst_90_counter = cv.rotate(img, cv.ROTATE_90_COUNTERCLOCKWISE)
cv.imshow("original", img)
cv.imshow("90", dst_90)
cv.imshow("180", dst_180)
cv.imshow("90 counter", dst_90_counter)
cv.waitKey(0)
cv.destroyAllWindows()
cv.waitKey(1)
math 모듈로 직접 구현import math
img = cv.imread(DOG_PATH)
rad = 45 * math.pi / 180
affine = np.array([[math.cos(rad), -math.sin(rad), 0], [math.sin(rad), math.cos(rad), 0]])
scale = (img.shape[1], img.shape[0])
dst = cv.warpAffine(img, affine, scale)
cv.imshow("img", img)
cv.imshow("rotate", dst)
cv.waitKey(0)
cv.destroyAllWindows()
cv.waitKey(1)
getRotationMatrix2D 이용img = cv.imread(DOG_PATH)
center = (int(img.shape[1]/2), int(img.shape[0]/2))
scale = (img.shape[1], img.shape[0])
affine = cv.getRotationMatrix2D(center, 45, 1)
dst = cv.warpAffine(img, affine, scale)
cv.imshow("img", img)
cv.imshow("rotate", dst)
cv.waitKey(0)
cv.destroyAllWindows()
cv.waitKey(1)
cv2.getPerspectiveTransform(src, dst) -> matcv2.warpPerspective(img, mat, (width, height))img = cv.imread(CARD_PATH)
width, height = 600, 350
src = np.array([[54,261], [981,128], [1213,560], [194,735]], dtype=np.float32)
dst = np.array([[0,0], [width,0], [width,height], [0,height]], dtype=np.float32)
mat = cv.getPerspectiveTransform(src, dst)
result = cv.warpPerspective(img, mat, (width, height))
cv.imshow("img", img)
cv.imshow("warped", result)
cv.waitKey(0)
cv.destroyAllWindows()
cv.waitKey(1)
OpenCV 용어들이 전에 음향 일을 하면서 배웠던 용어들이나 영상 관련 용어들이 많이 나와서 이해하기가 한결 수월한 것 같다. 나중에는 OpenCV를 사용해서 어떤 사물인지 인식하는 등의 기능도 다뤄본다고 해서 빨리 배워보고 싶다.