전처리 과정 - 3. 악보 이미지 정규화
노이즈 및 오선은 모두 제거 되었고 이제 악보 이미지 정규화가 필요합니다.
어떤 악보가 입력되던 악보의 이미지가 항상 같은 비율을 가지게끔 하면
추후 탐색 및 인식에서 이점으로 작용하기 때문입니다.
앞전에 오선의 좌표들을 모두 구했고 이를 이용하면 정규화가 가능합니다.
avg_distance = 0
lines = int(len(staves) / 5) # 보표의 개수
for line in range(lines):
for staff in range(4):
staff_above = staves[line * 5 + staff]
staff_below = staves[line * 5 + staff + 1]
avg_distance += abs(staff_above - staff_below) # 오선의 간격을 누적해서 더해줌
avg_distance /= len(staves) - lines # 오선 간의 평균 간격
오선 간의 평균 간격을 구하는 코드입니다.
오선의 칸은 보표마다 4개씩 존재하며 모든 칸의 간격을 누적해둔후 칸의 개수만큼 나눠주면 됩니다.
칸의 개수는 오선보다 1개씩 작으니 총 오선의 개수 - 보표의 개수로 구할 수 있습니다.
height, width = image.shape # 이미지의 높이와 넓이
weight = standard / avg_distance # 기준으로 정한 오선 간격을 이용해 가중치를 구함
new_width = int(width * weight) # 이미지의 넓이에 가중치를 곱해줌
new_height = int(height * weight) # 이미지의 높이에 가중치를 곱해줌
가중치를 구하는 코드입니다.
만약 어떤 악보가 입력되어도 오선 한칸의 간격을 10pixel로 정하고자 한다면
10 / 오선 평균 간격을 통해 가중치를 구할 수 있습니다.
오선의 평균 간격이 8이고 가중치는 1.25가 되겠죠.
즉 이미지의 넓이와 높이에 1.25를 곱해야 오선의 간격이 10이 된다고 생각하시면 됩니다.
standard라는 변수가 갖게될 오선 간격을 의미합니다.
image = cv2.resize(image, (new_width, new_height)) # 이미지 리사이징
ret, image = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) # 이미지 이진화
staves = [x * weight for x in staves] # 오선 좌표에도 가중치를 곱해줌
가중치가 곱해진 넓이와 높이로 이미지를 리사이징해줍니다.
리사이징 과정에 이진화된 이미지가 그레이스케일 이미지로 변하기때문에
다시금 이진화를 진행해주면 되고, 오선 좌표에도 가중치를 곱해줍니다.
# modules.py
import cv2
import numpy as np
import functions as fs
def normalization(image, staves, standard):
avg_distance = 0
lines = int(len(staves) / 5) # 보표의 개수
for line in range(lines):
for staff in range(4):
staff_above = staves[line * 5 + staff]
staff_below = staves[line * 5 + staff + 1]
avg_distance += abs(staff_above - staff_below) # 오선의 간격을 누적해서 더해줌
avg_distance /= len(staves) - lines # 오선 간의 평균 간격
height, width = image.shape # 이미지의 높이와 넓이
weight = standard / avg_distance # 기준으로 정한 오선 간격을 이용해 가중치를 구함
new_width = int(width * weight) # 이미지의 넓이에 가중치를 곱해줌
new_height = int(height * weight) # 이미지의 높이에 가중치를 곱해줌
image = cv2.resize(image, (new_width, new_height)) # 이미지 리사이징
ret, image = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) # 이미지 이진화
staves = [x * weight for x in staves] # 오선 좌표에도 가중치를 곱해줌
return image, staves
# Main.py
import cv2
import os
import numpy as np
import functions as fs
import modules
# 이미지 불러오기
resource_path = os.getcwd() + "/resource/"
image_0 = cv2.imread(resource_path + "music.jpg")
# 1. 보표 영역 추출 및 그 외 노이즈 제거
image_1 = modules.remove_noise(image_0)
# 2. 오선 제거
image_2, staves = modules.remove_staves(image_1)
# 3. 악보 이미지 정규화
image_3, staves = modules.normalization(image_2, staves, 10)
# 이미지 띄우기
cv2.imshow('image', image_3)
k = cv2.waitKey(0)
if k == 27:
cv2.destroyAllWindows()
'인공지능 > 컴퓨터비전' 카테고리의 다른 글
[OpenCV/Python] 악보 인식(디지털 악보 인식) - 5 (0) | 2021.08.05 |
---|---|
[OpenCV/Python] 악보 인식(디지털 악보 인식) - 4 (0) | 2021.08.04 |
[OpenCV/Python] 악보 인식(디지털 악보 인식) - 2 (0) | 2021.08.04 |
[OpenCV/Python] 악보 인식(디지털 악보 인식) - 1 (0) | 2021.08.04 |
[OpenCV/악보인식] 광학 음악 인식 기반 자동 편곡 시스템 - 5 (2) | 2021.05.27 |
댓글