python 인증 코드 인식 튜 토리 얼 의 이용 투영 법,연결 도 메 인 법 분할 그림

머리말
오늘 이 글 은 인증 코드 를 어떻게 나 누 는 지 기록 하 는데 사용 되 는 주요 라 이브 러 리 는 Pillow 와 Linux 의 이미지 처리 도구 인 GIMP 입 니 다.먼저 고정된 위치 와 너비,접착 이 없고 간섭 이 없 는 예 를 가정 하여 Pillow 를 사용 하여 그림 을 자 르 는 방법 을 배 워 보 세 요.
GIMP 를 사용 하여 그림 을 연 후,추가 번호 로 그림 을 확대 한 후,View->Show Grid 를 클릭 하여 격자 선 을 표시 합 니 다.

그 중에서 각 정사각형 의 길 이 는 10 픽 셀 이기 때문에 숫자 1 절단 좌 표 는 왼쪽 20,위 20,오른쪽 40,아래 70 이다.이 를 통 해 나머지 세 숫자의 절단 위 치 를 알 수 있다.
코드 는 다음 과 같 습 니 다:

from PIL import Image
p = Image.open("1.png")
#         、 、 、 
cuts = [(20,20,40,70),(60,20,90,70),(100,10,130,60),(140,20,170,50)]
for i,n in enumerate(cuts,1):
 temp = p.crop(n) #   crop      
 temp.save("cut%s.png" % i)
절단 후 4 장의 그림 을 얻 을 수 있 습 니 다:

그렇다면 문자 위치 가 고정 되 지 않 으 면 어떻게 합 니까?지금 은 무 작위 위치 너비,접착,간섭 선 이 없 는 상황 을 가정 한다.
첫 번 째 방법 이자 가장 간단 한 방법 은'투영 법'이 라 고 한다.원 리 는 이치 화 된 그림 을 수직 방향 으로 투영 하여 투영 후의 극치 에 따라 경 계 를 분할 하 는 것 이다.여기 서 나 는 여전히 위의 인증 코드 그림 을 사용 하여 시범 을 보 여 준다.

def vertical(img):
 """               """
 pixdata = img.load()
 w,h = img.size
 ver_list = []
 #     
 for x in range(w):
 black = 0
 for y in range(h):
  if pixdata[x,y] == 0:
  black += 1
 ver_list.append(black)
 #     
 l,r = 0,0
 flag = False
 cuts = []
 for i,count in enumerate(ver_list):
 #      0
 if flag is False and count > 0:
  l = i
  flag = True
 if flag and count == 0:
  r = i-1
  flag = False
  cuts.append((l,r))
 return cuts

p = Image.open('1.png')
b_img = binarizing(p,200)
v = vertical(b_img)
vertical 함 수 를 통 해 우 리 는 모든 검은색 픽 셀 이 X 축 에 투 영 된 후 좌우 경 계 를 포함 하 는 위 치 를 얻 었 다.인증 코드 에 아무런 방해 가 없 기 때문에 나의 한도 값 은 0 으로 설정 되 었 다.binarizing 함수 에 대해 서 는이전 문장 을 참고 하 다
출력 은 다음 과 같 습 니 다:

[(21, 37), (62, 89), (100, 122), (146, 164)]
투영 법 은 좌우 경 계 를 우리 가 손 으로 보 는 것 과 비슷 하 다 는 것 을 알 수 있다.상하 경계 에 대해 게 으 름 을 피 우 는 사람 은 0 과 그림 의 높이 를 직접 사용 할 수도 있 고 수평 방향 으로 투영 할 수도 있다.여기 서 관심 이 있 는 동료 들 은 스스로 시도 할 수 있다.
그러나 문자 간 에 붙 어 있 는 경우 투영 법 에 분할 오류 가 발생 할 수 있 습 니 다.예 를 들 어 위의 글 에서:

한도 값 을 5 로 수정 한 후 투영 법 이 제시 한 좌우 경 계 는 다음 과 같다.

[(5, 27), (33, 53), (59, 108)]
마지막 6 과 9 숫자 가 잘 리 지 않 은 것 이 분명 하 다.
한도 값 을 7 로 수정 한 결 과 는:

[(5, 27), (33, 53), (60, 79), (83, 108)]
그래서 간단 한 접착 상황 에 대해 한도 값 을 조정 하 는 것 도 해결 할 수 있다.
두 번 째 방법 은 CFS 연통 역 분할법 이 라 고 한다.원 리 는 모든 문자 가 하나의 단독 연결 도 메 인 으로 구성 된다 고 가정 하 는 것 이다.다시 말 하면 접착 되 지 않 고 검은색 픽 셀 을 찾 아 판단 하기 시작 하 는 것 이다.연 결 된 검은색 픽 셀 이 모두 옮 겨 다 니 며 표 시 될 때 까지 이 문자 의 분할 위 치 를 판단 할 수 있다.알고리즘 은 다음 과 같 습 니 다.
4.567917.이치 화 된 그림 을 왼쪽 에서 오른쪽으로,위 에서 아래로 옮 겨 다 니 며 검은색 픽 셀 을 만 났 고 이 픽 셀 에 접근 하지 않 았 다 면 이 픽 셀 을 스 택 에 넣 고 방문 한 것 으로 표시 합 니 다
  • 스 택 이 비어 있 지 않 으 면 주변 8 개의 픽 셀 을 계속 탐지 하고 2 단 계 를 수행 합 니 다.스 택 이 비어 있 으 면 문자 블록 을 탐지 한 것 을 의미 합 니 다
  • 4.567917.탐측 이 끝나 면 몇 글자 가 확정 된다코드 는 다음 과 같 습 니 다:
    
    import queue
    
    def cfs(img):
     """                """
     pixdata = img.load()
     w,h = img.size
     visited = set()
     q = queue.Queue()
     offset = [(-1,-1),(0,-1),(1,-1),(-1,0),(1,0),(-1,1),(0,1),(1,1)]
     cuts = []
     for x in range(w):
      for y in range(h):
       x_axis = []
       #y_axis = []
       if pixdata[x,y] == 0 and (x,y) not in visited:
        q.put((x,y))
        visited.add((x,y))
       while not q.empty():
        x_p,y_p = q.get()
        for x_offset,y_offset in offset:
         x_c,y_c = x_p+x_offset,y_p+y_offset
         if (x_c,y_c) in visited:
          continue
         visited.add((x_c,y_c))
         try:
          if pixdata[x_c,y_c] == 0:
           q.put((x_c,y_c))
           x_axis.append(x_c)
           #y_axis.append(y_c)
         except:
          pass
       if x_axis:
        min_x,max_x = min(x_axis),max(x_axis)
        if max_x - min_x > 3:
         #     3      ,      
         cuts.append((min_x,max_x))
     return cuts
    호출 후 출력 결 과 는 투영 법 을 사용 하 는 것 과 같 습 니 다.그리고 인터넷 에'홍수 충전(Flood Fill)'이라는 방법 도 있 는데 연결 역 과 같은 것 같 습 니 다.
    총결산
    이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

    좋은 웹페이지 즐겨찾기