使用Python在图像验证码中删除行
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了使用Python在图像验证码中删除行,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3530字,纯文字阅读大概需要6分钟。
内容图文
我使用了这个链接 – How to remove line from captcha completely并编辑了提供的代码,以便从我在下面给出的虚拟验证码中删除线条
lineRemoval.py
from PIL import Image,ImageFilter
from scipy.misc import toimage
from operator import itemgetter
from skimage import measure
import numpy as np
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 i>=0 and i<len(img_removed_line)-1:
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 i>=0 and i<len(img_removed_line)-1:
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
if __name__ == '__main__':
image = cv2.imread("captcha.png")
img = Image.fromarray(image)
p = preprocessing()
imgNew = p.pre_proc_image(img)
cv2.imshow("Input", np.array(image))
cv2.imshow('Output', np.array(imgNew, dtype=np.uint8))
cv2.waitKey(0)
代码没有错误,但是输出图像没有删除任何行,看起来有点像这样:
我希望输出完全没有任何形式的线条或至少降低它们的强度,以便以后它可以与pytesseract一起使用来识别验证码中提到的字母.
更新
验证码数据集中几乎没有异常,其中线具有相同的强度,如下所示
在对这些图像进行阈值处理后,它们中还有一些线条
浏览网后,我发现你可以在这些图像上使用侵蚀和扩张技术去除这些线,但是使用这些技术,pytesseract无法识别这些字符,因为我没有得到非常清晰的输出.
是否有任何其他建议的技术可以应用于这些图像集,以便以后pytesseract可以识别这些字符?
解决方法:
在这种特殊情况下,线条的密度似乎小于字符密度.
所以通过应用一些阈值方法,你可以删除行:
例如,以下行给出了这个:
retval,image = cv2.threshold(image,12,255,cv2.THRESH_BINARY)
稍后通过应用一些噪声消除方法,如中位数(来自您自己的代码),您可以得到以下结果:
内容总结
以上是互联网集市为您收集整理的使用Python在图像验证码中删除行全部内容,希望文章能够帮你解决使用Python在图像验证码中删除行所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。