如何完全从验证码中删除线 [英] how to remove line from captcha completely
问题描述
我是一名python程序员,专门用图像处理工具箱在python中编写了很多程序。
我写了一个删除此验证码的程序:
https://ibb.co/ncED3v
首先,我通过中值过滤器提高图像可见性
I am a python programmer and wrote a lot of program in python specially by image processing toolbox. I wrote a program to remove line from this captcha: https://ibb.co/ncED3v first of all I improve image visibility by median filter
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
最后我按其位置删除行:
finally I remove line by its position:
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
但在某些情况下,行不会完全删除,我会得到一些带有噪音的验证码图像:
https://ibb.co/bKPKbF
请帮帮我一些想法!
but line don't removed completely in some cases and I get the captcha image with some noise: https://ibb.co/bKPKbF please help me with some idea!
推荐答案
问题解决了!听到的是我编辑的python代码。这会从验证码中删除一行。得到它并享受!:))
the problem solved! hear is my edited python code. this removes line from captcha. get it and enjoy!:))
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
这篇关于如何完全从验证码中删除线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!