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 개 를 받 습 니 다:

이 사진 을 보면 절 분 은 성 공 했 지만 효 과 는 별로 다.또한 현재 코드 는 두 글자 가 붙 어 있 는 상황 만 나 눌 수 있 고 물방울 알고리즘 의 정 수 를 깨 달 은 파트너 가 여러 글자 로 붙 어 있 는 상황 으로 바 꿔 볼 수 있 습 니 다.
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

좋은 웹페이지 즐겨찾기