2017-03-11 1 views
1

저는 python 프로그래머입니다. 특별히 python으로 이미지 처리 도구 상자로 많은 프로그램을 작성했습니다.captcha에서 줄을 완전히 제거하는 방법

def eliminate_zeros(self,vector): 
    return [(dex,v) for (dex,v) in enumerate(vector) if v!=0 ] 

def get_line_position(self,img): 
    sumx=img.sum(axis=0) 
    list_without_zeros=self.eliminate_zeros(sumx) 
    min1,min2=heapq.nsmallest(2,list_without_zeros,key=itemgetter(1)) 
    l=[dex for [dex,val] in enumerate(sumx) if val==min1[1] or val==min2[1]] 
    mindex=[l[0],l[len(l)-1]] 
    cols=img[:,mindex[:]] 
    col1=cols[:,0] 
    col2=cols[:,1] 
    col1_without_0=self.eliminate_zeros(col1) 
    col2_without_0=self.eliminate_zeros(col2) 
    line_length=len(col1_without_0) 
    dex1=col1_without_0[round(len(col1_without_0)/2)][0] 
    dex2=col2_without_0[round(len(col2_without_0)/2)][0] 
    p1=[dex1,mindex[0]] 
    p2=[dex2,mindex[1]] 
    return p1,p2,line_length 

가 마침내 제거 라인 :

def apply_median_filter(self,img): 
    img_gray=img.convert('L') 
    img_gray=cv2.medianBlur(np.asarray(img_gray),3) 
    img_bw=(img_gray>np.mean(img_gray))*255 
    return img_bw 

그때 내가 줄을 제거하려고 중간 필터에 의해 모든 https://ibb.co/ncED3v 처음에는 개선 이미지 가시성 : 나는이 보안 문자에서 줄을 제거 할 수있는 프로그램을 작성 그 위치에 따라 :

def remove_line(self,p1,p2,LL,img): 
    m=(p2[0]-p1[0])/(p2[1]-p1[1]) if p2[1]!=p1[1] else np.inf 
    w,h=len(img),len(img[0]) 
    x=[x for x in range(w)] 
    y=[p1[0]+k for k in [m*t for t in [v-p1[1] for v in x]]] 
    img_removed_line=img 
    for dex in range(w): 
     i,j=np.round([y[dex],x[dex]]) 
     i=int(i) 
     j=int(j) 
     rlist=[] 
     while True: 
      f1=i 
      if img_removed_line[i,j]==0 and img_removed_line[i-1,j]==0: 
       break 
      rlist.append(i) 
      i=i-1 

     i,j=np.round([y[dex],x[dex]]) 
     i=int(i) 
     j=int(j) 
     while True: 
      f2=i 
      if img_removed_line[i,j]==0 and img_removed_line[i+1,j]==0: 
       break 
      rlist.append(i) 
      i=i+1 
     print([np.abs(f2-f1),[LL+1,LL,LL-1]]) 
     if np.abs(f2-f1) in [LL+1,LL,LL-1]: 
      rlist=list(set(rlist)) 
      img_removed_line[rlist,j]=0 

    return img_removed_line 

그러나 어떤 경우에는 라인이 완전히 제거되지 않고 약간의 잡음이있는 captcha 이미지 : https://ibb.co/bKPKbF 몇 가지 아이디어로 도와주세요!

답변

2

문제가 해결되었습니다. 듣고 내 편집 된 파이썬 코드입니다. 이것은 captcha에서 줄을 제거합니다. 그것을 얻고 즐기십시오! :))

from PIL import Image,ImageFilter 
from scipy.misc import toimage 
from operator import itemgetter 
from skimage import measure 
import numpy as np 
import copy 
import heapq 
import cv2 
import matplotlib.pyplot as plt 
from scipy.ndimage.filters import median_filter 

#---------------------------------------------------------------- 
class preprocessing: 
def pre_proc_image(self,img): 
    #img_removed_noise=self.apply_median_filter(img) 
    img_removed_noise=self.remove_noise(img) 
    p1,p2,LL=self.get_line_position(img_removed_noise) 
    img=self.remove_line(p1,p2,LL,img_removed_noise) 
    img=median_filter(np.asarray(img),1) 
    return img 

def remove_noise(self,img): 
    img_gray=img.convert('L') 
    w,h=img_gray.size 
    max_color=np.asarray(img_gray).max() 
    pix_access_img=img_gray.load() 
    row_img=list(map(lambda x:255 if x in range(max_color-15,max_color+1) else 0,np.asarray(img_gray.getdata()))) 
    img=np.reshape(row_img,[h,w]) 
    return img 

def apply_median_filter(self,img): 
    img_gray=img.convert('L') 
    img_gray=cv2.medianBlur(np.asarray(img_gray),3) 
    img_bw=(img_gray>np.mean(img_gray))*255 
    return img_bw 

def eliminate_zeros(self,vector): 
    return [(dex,v) for (dex,v) in enumerate(vector) if v!=0 ] 

def get_line_position(self,img): 
    sumx=img.sum(axis=0) 
    list_without_zeros=self.eliminate_zeros(sumx) 
    min1,min2=heapq.nsmallest(2,list_without_zeros,key=itemgetter(1)) 
    l=[dex for [dex,val] in enumerate(sumx) if val==min1[1] or val==min2[1]] 
    mindex=[l[0],l[len(l)-1]] 
    cols=img[:,mindex[:]] 
    col1=cols[:,0] 
    col2=cols[:,1] 
    col1_without_0=self.eliminate_zeros(col1) 
    col2_without_0=self.eliminate_zeros(col2) 
    line_length=len(col1_without_0) 
    dex1=col1_without_0[round(len(col1_without_0)/2)][0] 
    dex2=col2_without_0[round(len(col2_without_0)/2)][0] 
    p1=[dex1,mindex[0]] 
    p2=[dex2,mindex[1]] 
    return p1,p2,line_length 

def remove_line(self,p1,p2,LL,img): 
    m=(p2[0]-p1[0])/(p2[1]-p1[1]) if p2[1]!=p1[1] else np.inf 
    w,h=len(img),len(img[0]) 
    x=list(range(h)) 
    y=list(map(lambda z : int(np.round(p1[0]+m*(z-p1[1]))),x)) 
    img_removed_line=list(img) 
    for dex in range(h): 
     i,j=y[dex],x[dex] 
     i=int(i) 
     j=int(j) 
     rlist=[] 
     while True: 
      f1=i 
      if img_removed_line[i][j]==0 and img_removed_line[i-1][j]==0: 
       break 
      rlist.append(i) 
      i=i-1 

     i,j=y[dex],x[dex] 
     i=int(i) 
     j=int(j) 
     while True: 
      f2=i 
      if img_removed_line[i][j]==0 and img_removed_line[i+1][j]==0: 
       break 
      rlist.append(i) 
      i=i+1 
     if np.abs(f2-f1) in [LL+1,LL,LL-1]: 
      rlist=list(set(rlist)) 
      for k in rlist: 
       img_removed_line[k][j]=0 

    return img_removed_line 
관련 문제