첫번째 시연 후 이런저런 피드백을 받아 수용가능한 사항들을 반영해 코드를 업그레이드 하였다. 우선, 오프라인에서도 코드실행이 가능하도록 코랩에서 VScode로 개발환경을 이사하였다
기존에는 구역별로 나누어 이미지를 만들고 색칠했다면 지금은 어느정도 경계가 있는 지도에 이미지맵에 구역으로 안들어갔으면 하는 부분만 까만색(#000000)으로 칠해주면 된다! 이미지 한개를 알아서 나눠 인식하고 나눠서 구역을 따준다!
기존에는 영역별 좌표 배열을 터미널에 출력하여 사용자가 좌표배열을 이용하여 이미지맵 html을 직접 생성해야 했지만 현재 버전에서는 구역별로인식하고 자동으로 html파일까지 떨궈준다
이미지크기에 비례하여 좌표수가 늘어나기 때문에 큰이미지들을 다룰때 html파일도 같이 길어지는 것을 방지하기 위해 축소 계수를 사용하여 좌표의 밀도를 조정할 수 있게 했다
MSTR 플러그인에서는 같은 애트리뷰트에 해당하는 구역이 여러개인 경우 html파일의 가장위의 구역에 값이나 타이틀을 뿌려준다 그래서 가장 넓은 지역에 값을 뿌려주도록 좌표의 수가 많은 구역별로 내림차순 정렬을 하기로했다 (예를들어 경상북도의 독도, 울릉도, 내륙 세가지 구역을 가진 경우 가장 큰 내륙에 값이 뿌려지도록..)
import cv2
import numpy as np
class coords:
def __init__(self) -> None:
pass
def extract(imgpath):
# 원본 이미지 불러오기
origin_img = cv2.imread(imgpath)
# 작업할 이미지 불러오기
img = cv2.imread(imgpath)
# 이미지 그레이 전환
imgray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
# 흑과 백으로 임계(threshold) 분할
test, thresh = cv2.threshold(imgray, 127, 255, 0)
contours, hierarchy = cv2.findContours(
thresh, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE) # contour(외곽선)를 찾아냄.(연속된 좌표점)
# 원본 이미지에 contour(외곽선)을 그림, 빨간색(0, 0, 255), 두께 1로 -- 확인용
cv2.drawContours(origin_img, contours, -1, (0, 0, 255), 1)
# 이미지 출력
cv2.imshow('result', origin_img)
# 아무키나 누르면
cv2.waitKey(0)
# 모든창 닫기
cv2.destroyAllWindows()
temp = list(contours)
temp.sort(key=len)
temp.reverse()
result = list()
for i in range(len(temp)):
# 작은 구역은 좌표를 출력하지 않고 PASS
if len(temp[i]) < 10:
continue
result.append(temp[i])
return result
def printhtml(contours, n=1):
# 좌표 생략 계수 default는 1이며 n을 함께 입력시 좌표의 갯수가 n분의 1로 줄어든다
num = n
# ---------------- 완성된 contours로 html 파일 제작 -----------------
f = open('result.html', 'w')
f.write('''<!DOCTYPE html>
<html>
<head></head>
<body>
<img src="''' + imgpath + ''' "usemap = "#test"/>
<map name="test">
''')
for i in range(len(contours)):
# contours 간격을 n분의 1로 조정하여 출력
arr = np.array(contours[i][0:len(contours[i]):num])
# N차원의 contours 배열을 1차원으로 축소
result = arr.ravel()
f.write('<area shape=\"poly\" alt=\"\" title=\"' +
str(i+1)+'\" coords=\"')
# 배열사이에 들어갈 문자를 지정한 뒤 출력 and 첫번째 좌표를 마지막에 추가
f.write(str(result).replace("[", "").replace(
"]", "").replace(" ", ",")) # +result[0:2]
f.write('" href="" target="_self" />\n')
f.write('''
</map>
</body>
</html>''')
# 이미지 경로 확장자까지 입력하기
imgpath = "이름을 입력해주세요"
contours = coords.extract(imgpath)
# N은 좌표 축소 계수
coords.printhtml(contours, N)
피드백의 피드백을 거듭하여... 현재 임의로 1부터 N까지 타이틀을 부여하고 HTML을 웹브라우저로 열어 일일히 수정하는 부분을 이미지창이 열렸을때 마우스 이벤트와 키보드 인풋을 통해 해당하는 값을 받아 html로 한번에 내렸으면 좋겠다는 의견이 있다.
MSTR에선 이미지맵의 alt값을 애트리뷰트의 속성으로 인식하기에 이 라벨링 과정이 중요하다...흑