python 인증 코드 인식 튜 토리 얼 의 물방울 알고리즘 분할 그림
물방울 알고리즘 은 손 으로 쓴 접착 문 자 를 분할 하 는 알고리즘 으로 기 존의 직선 식 분할 과 달리 물방울 의 굴 림 을 모 의 하고 물방울 의 굴 림 경 로 를 통 해 문 자 를 분할 하면 직선 절단 으로 인 한 과도 한 분할 문 제 를 해결 할 수 있다.
머리말
전에 말 했 듯 이 붙 어 있 는 문자 에 대해 물방울 알고리즘 을 사용 하여 분할 을 해결 할 수 있다 고 했 지만 지능 이 급 한 저 는 이 알고리즘 의 정 수 를 깨 닫 지 못 했 습 니 다.다행히 작은 파트너 가 관련 성 을 실 현 했 습 니 다코드
나 는 위의 코드 를 약간 수정 하 였 으 며,동시에 python 3 의 코드 로 업그레이드 하 였 다.
아니면 이 그림 을 예 로 들 면:
예전 에 우 리 는 이런 간단 한 접착 이 한도 값 을 제어 하여 분할 을 실현 할 수 있다 는 것 을 알 고 있 었 다.여기 서 우 리 는 물방울 알고리즘 을 사용 했다.
먼저이전 글 중소 개 된 수직 투영 또는 연결 도 메 인 을 사용 하여 먼저 절단 처 리 를 한 번 하고 결 과 는 다음 과 같다.
마지막 접착 상황 에 맞추어 물방울 알고리즘 처리:
from itertools import groupby
def binarizing(img,threshold):
""" image 、 """
img = img.convert("L") #
pixdata = img.load()
w, h = img.size
# ,
for y in range(h):
for x in range(w):
if pixdata[x, y] < threshold:
pixdata[x, y] = 0
else:
pixdata[x, y] = 255
return img
def vertical(img):
""" """
pixdata = img.load()
w,h = img.size
result = []
for x in range(w):
black = 0
for y in range(h):
if pixdata[x,y] == 0:
black += 1
result.append(black)
return result
def get_start_x(hist_width):
"""
hist_width 4
"""
mid = len(hist_width) // 2 # py3 py2
temp = hist_width[mid-4:mid+5]
return mid - 4 + temp.index(min(temp))
def get_nearby_pix_value(img_pix,x,y,j):
""" 5 """
if j == 1:
return 0 if img_pix[x-1,y+1] == 0 else 1
elif j ==2:
return 0 if img_pix[x,y+1] == 0 else 1
elif j ==3:
return 0 if img_pix[x+1,y+1] == 0 else 1
elif j ==4:
return 0 if img_pix[x+1,y] == 0 else 1
elif j ==5:
return 0 if img_pix[x-1,y] == 0 else 1
else:
raise Exception("get_nearby_pix_value error")
def get_end_route(img,start_x,height):
""" """
left_limit = 0
right_limit = img.size[0] - 1
end_route = []
cur_p = (start_x,0)
last_p = cur_p
end_route.append(cur_p)
while cur_p[1] < (height-1):
sum_n = 0
max_w = 0
next_x = cur_p[0]
next_y = cur_p[1]
pix_img = img.load()
for i in range(1,6):
cur_w = get_nearby_pix_value(pix_img,cur_p[0],cur_p[1],i) * (6-i)
sum_n += cur_w
if max_w < cur_w:
max_w = cur_w
if sum_n == 0:
#
max_w = 4
if sum_n == 15:
max_w = 6
if max_w == 1:
next_x = cur_p[0] - 1
next_y = cur_p[1]
elif max_w == 2:
next_x = cur_p[0] + 1
next_y = cur_p[1]
elif max_w == 3:
next_x = cur_p[0] + 1
next_y = cur_p[1] + 1
elif max_w == 5:
next_x = cur_p[0] - 1
next_y = cur_p[1] + 1
elif max_w == 6:
next_x = cur_p[0]
next_y = cur_p[1] + 1
elif max_w == 4:
if next_x > cur_p[0]:
#
next_x = cur_p[0] + 1
next_y = cur_p[1] + 1
if next_x < cur_p[0]:
next_x = cur_p[0]
next_y = cur_p[1] + 1
if sum_n == 0:
next_x = cur_p[0]
next_y = cur_p[1] + 1
else:
raise Exception("get end route error")
if last_p[0] == next_x and last_p[1] == next_y:
if next_x < cur_p[0]:
max_w = 5
next_x = cur_p[0] + 1
next_y = cur_p[1] + 1
else:
max_w = 3
next_x = cur_p[0] - 1
next_y = cur_p[1] + 1
last_p = cur_p
if next_x > right_limit:
next_x = right_limit
next_y = cur_p[1] + 1
if next_x < left_limit:
next_x = left_limit
next_y = cur_p[1] + 1
cur_p = (next_x,next_y)
end_route.append(cur_p)
return end_route
def get_split_seq(projection_x):
split_seq = []
start_x = 0
length = 0
for pos_x, val in enumerate(projection_x):
if val == 0 and length == 0:
continue
elif val == 0 and length != 0:
split_seq.append([start_x, length])
length = 0
elif val == 1:
if length == 0:
start_x = pos_x
length += 1
else:
raise Exception('generating split sequence occurs error')
# length 0, append
if length != 0:
split_seq.append([start_x, length])
return split_seq
def do_split(source_image, starts, filter_ends):
"""
: param starts: tuple of list
: param ends:
"""
left = starts[0][0]
top = starts[0][1]
right = filter_ends[0][0]
bottom = filter_ends[0][1]
pixdata = source_image.load()
for i in range(len(starts)):
left = min(starts[i][0], left)
top = min(starts[i][1], top)
right = max(filter_ends[i][0], right)
bottom = max(filter_ends[i][1], bottom)
width = right - left + 1
height = bottom - top + 1
image = Image.new('RGB', (width, height), (255,255,255))
for i in range(height):
start = starts[i]
end = filter_ends[i]
for x in range(start[0], end[0]+1):
if pixdata[x,start[1]] == 0:
image.putpixel((x - left, start[1] - top), (0,0,0))
return image
def drop_fall(img):
""" """
width,height = img.size
# 1
b_img = binarizing(img,200)
# 2
hist_width = vertical(b_img)
# 3
start_x = get_start_x(hist_width)
# 4
start_route = []
for y in range(height):
start_route.append((0,y))
end_route = get_end_route(img,start_x,height)
filter_end_route = [max(list(k)) for _,k in groupby(end_route,lambda x:x[1])] # groupby
img1 = do_split(img,start_route,filter_end_route)
img1.save('cuts-d-1.png')
start_route = list(map(lambda x : (x[0]+1,x[1]),filter_end_route)) # python3 map list
end_route = []
for y in range(height):
end_route.append((width-1,y))
img2 = do_split(img,start_route,end_route)
img2.save('cuts-d-2.png')
if __name__ == '__main__':
p = Image.open("cuts-2.png")
drop_fall(p)
실행 후 절 분 된 사진 2 개 를 받 습 니 다:이 사진 을 보면 절 분 은 성 공 했 지만 효 과 는 별로 다.또한 현재 코드 는 두 글자 가 붙 어 있 는 상황 만 나 눌 수 있 고 물방울 알고리즘 의 정 수 를 깨 달 은 파트너 가 여러 글자 로 붙 어 있 는 상황 으로 바 꿔 볼 수 있 습 니 다.
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
로마 숫자를 정수로 또는 그 반대로 변환그 중 하나는 로마 숫자를 정수로 변환하는 함수를 만드는 것이었고 두 번째는 그 반대를 수행하는 함수를 만드는 것이었습니다. 문자만 포함합니다'I', 'V', 'X', 'L', 'C', 'D', 'M' ; 문자열이 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.