요즘 들어서 삶이 꽤나 고단하다는 생각이 들고 있다. 그래도 뭐 매일매일 노력해야 하지 않나 싶다.
import cv2 as cv
import numpy as np
img = cv.imread("input.png", cv.IMREAD_GRAYSCALE)
_, bin_ = cv.threshold(img, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)
k = cv.getStructuringElement(cv.MORPH_RECT, (3,3))
eroded = cv.erode(bin_, k, iterations=1)
dilated = cv.dilate(bin_, k, iterations=1)
opened = cv.morphologyEx(bin_, cv.MORPH_OPEN, k, iterations=1)
closed = cv.morphologyEx(bin_, cv.MORPH_CLOSE, k, iterations=1)
: 집단 의 확률(빈도 누적)
: 집단 평균
import cv2 as cv
import numpy as np
img = cv.imread("input.png")
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
blur = cv.GaussianBlur(gray, (5,5), 0)
_, th = cv.threshold(blur, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)
# 글자 연결을 위한 클로징
k = cv.getStructuringElement(cv.MORPH_RECT, (3,3))
m = cv.morphologyEx(th, cv.MORPH_CLOSE, k, iterations=2)
# 컨투어 탐색 및 간단한 필터링
cnts, _ = cv.findContours(m, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
boxes = []
for c in cnts:
x,y,w,h = cv.boundingRect(c)
area = w*h
aspect = w / (h+1e-6)
if area > 200 and 1.2 < aspect < 15: # 예시 기준
boxes.append((x,y,w,h))
cv.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
cv.imwrite("contour_result.png", img)
Score map: class-balanced cross entropy
RBOX(AABB) 회귀: IoU loss + 각도 손실
QUAD 회귀: 스무스 L1에 길이 정규화 추가
import cv2 as cv
import numpy as np
# 1) 모델 로드
net = cv.dnn.readNet("frozen_east_text_detection.pb")
layerNames = [
"feature_fusion/Conv_7/Sigmoid", # score map (1ch)
"feature_fusion/concat_3" # geometry map (5ch: RBOX)
]
# 2) 전처리(blobs)
img = cv.imread("scene.jpg")
H, W = img.shape[:2]
inpW, inpH = 320, 320 # 32의 배수
blob = cv.dnn.blobFromImage(img, 1.0, (inpW, inpH),
(123.68,116.78,103.94), swapRB=True, crop=False)
# 3) 추론
net.setInput(blob)
(scores, geometry) = net.forward(layerNames) # scores: (1,1,h,w), geometry: (1,5,h,w)
# 4) 디코딩(RBOX)
def decode(scores, geom, scoreThr=0.5):
numRows, numCols = scores.shape[2:4]
boxes, confidences = [], []
for y in range(numRows):
scoresData = scores[0,0,y]
x0 = geom[0,0,y]; x1 = geom[0,1,y]; x2 = geom[0,2,y]; x3 = geom[0,3,y]
angles = geom[0,4,y]
for x in range(numCols):
if scoresData[x] < scoreThr:
continue
angle = angles[x]
cos, sin = np.cos(angle), np.sin(angle)
h = x0[x] + x2[x]; w = x1[x] + x3[x]
# feature map stride = 4
offsetX, offsetY = x*4.0, y*4.0
endX = int(offsetX + (cos * x1[x]) + (sin * x2[x]))
endY = int(offsetY - (sin * x1[x]) + (cos * x2[x]))
startX = int(endX - w); startY = int(endY - h)
boxes.append((startX, startY, endX, endY))
confidences.append(float(scoresData[x]))
return boxes, confidences
boxes, confs = decode(scores, geometry, 0.5)
# 5) NMS 및 원본 좌표 보정
indices = cv.dnn.NMSBoxes(
[cv.Rect(b[0],b[1],b[2]-b[0],b[3]-b[1]) for b in boxes],
confs, 0.5, 0.4
)
rW, rH = W/float(inpW), H/float(inpH)
for i in indices:
i = int(i)
(sx, sy, ex, ey) = boxes[i]
x1, y1, x2, y2 = int(sx*rW), int(sy*rH), int(ex*rW), int(ey*rH)
cv.rectangle(img, (x1,y1), (x2,y2), (0,255,0), 2)
cv.imwrite("east_result.png", img)