前言
本文主要对一般的文字点选验证码图片进行坐标获取,起初碰到这类型验证也是大多采用第三方平台进行定位,所以这次也想挑战一下。本次学习中参考了很多资料,也有自己的思考🤔对本人小白来说也是次小突破吧!希望对亲们有所帮助~❤️
一、思路
- 将原图上、下两部分截取为目标图片和比对图片
- 创建一张与目标图片尺寸相同的黑色背景图,将目标图片上的文字像素拷贝至新图
- 获取新图中文字位置的上、下、左、右边界坐标
- 根据边界坐标通过像素值的计算来定位各文字的中心坐标
- 根据文字的中心坐标截取4份图片,并做黑白转换和图片腐蚀化处理
- 将比对图片上的文字进行截取,共4份
- 识别8份图片中的文字,并做比对得出相对应的坐标位置
二、步骤
import cv2
import numpy as np
from PIL import Image
from baiduApi import BaiduApi
def crop_09image(self):
"""
裁剪原图为上、下两部分
"""
im = cv2.imread('09.jpg')
height, width = im.shape[0:2] # 读取图片高,宽
imageUp = im[0:height - 40, 0:width] # 截取图片上部分
imageDown = im[height - 40:height, 0:125] # 截取图片下部分
cv2.imwrite('imageUp.jpg',imageUp)
cv2.imwrite('imageDown.jpg',imageDown)
return imageUp,imageDown
![](https://img-blog.csdnimg.cn/eed8872d526c473a95c4566d0990728d.jpeg)
![](https://img-blog.csdnimg.cn/d23d15575eaa470cad36e0e83ff4aa62.jpeg)
第三步:文字像素拷贝
def imageUp_process(self):
"""
创建背景全黑的新图,将imageUp上的文字像素拷贝到新图
"""
imUp = cv2.imread('imageUp.jpg')
h,w = imUp.shape[0:2] # 读取imUp的高、宽 344 344
# 创建新的全黑图片
imNew = np.zeros((h,w,3),np.uint8)
cv2.imwrite('imageNew.jpg',imNew)
# 拷贝文字
img1 = np.array(imUp) # imageUp,imageNew数据转换成numpy类型
img2 = np.array(imNew)
# 遍历所有像素点
for y in range(h):
for x in range(w):
# 判断该点的像素值是否在(255,255,255)附近
if 240 <= img1[y, x, 0] <= 255 and 240 <= img1[y, x, 1] <= 255 and 240 <= img1[y, x, 2] <= 255:
# img1的像素拷贝到img2
img2[y, x, 0] = img1[y, x, 0]
img2[y, x, 1] = img1[y, x, 1]
img2[y, x, 2] = img1[y, x, 2]
cv2.imwrite('imageNew2.jpg',img2)
![](https://img-blog.csdnimg.cn/1bf2977e586e48e7a17c713efab665a9.jpeg)
第四步:对imageNew2图片灰度、二值化处理,然后遍历图片获取像素值为1的所有坐标位置,获得左、右、上、下、边界坐标
参考文章:
使用python PIL库实现简单验证码的去噪_锅炉房刘大爷的博客-CSDN博客
针对文字图片使用pillow对图片进行操作并判断图片相似度_kong_and_white的博客-CSDN博客_pillow 图像识别
def get_bin_table(self):
"""
获取灰度转二值的映射table
"""
table = []
threshold = 140
for i in range(256):
if i < threshold:
table.append(0)
else:
table.append(1)
return table
def sum_9_region(self,img, x, y):
"""
确定白色像素的坐标
"""
cur_pixel = img.getpixel((x, y))
width = img.width
height = img.height
if cur_pixel == 0: # 黑色邻域不统计
return 0
if y == 0: # 第一行
if x == 0: # 左上顶点,4邻域
# 中心点旁边3个点
sum = cur_pixel \
+ img.getpixel((x, y + 1)) \
+ img.getpixel((x + 1, y)) \
+ img.getpixel((x + 1, y + 1))
return 4 - sum
elif x == width - 1: # 右上顶点
sum = cur_pixel \
+ img.getpixel((x, y + 1)) \
+ img.getpixel((x - 1, y)) \
+ img.getpixel((x - 1, y + 1))
return 4 - sum
else: # 最上非顶点,6邻域
sum = img.getpixel((x - 1, y)) \
+ img.getpixel((x - 1, y + 1)) \
+ cur_pixel \
+ img.getpixel((x, y + 1)) \
+ img.getpixel((x + 1, y)) \
+ img.getpixel((x + 1, y + 1))
return 6 - sum
elif y == height - 1: # 最下面一行
if x == 0: # 左下顶点
# 中心点旁边3个点
sum = cur_pixel \
+ img.getpixel((x + 1, y)) \
+ img.getpixel((x + 1, y - 1)) \
+ img.getpixel((x, y - 1))
return 4 - sum
elif x == width - 1: # 右下顶点
sum = cur_pixel \
+ img.getpixel((x, y - 1)) \
+ img.getpixel((x - 1, y)) \
+ img.getpixel((x - 1, y - 1))
return 4 - sum
else: # 最下非顶点,6邻域
sum = cur_pixel \
+ img.getpixel((x - 1, y)) \
+ img.getpixel((x + 1, y)) \
+ img.getpixel((x, y - 1)) \
+ img.getpixel((x - 1, y - 1)) \
+ img.getpixel((x + 1, y - 1))
return 6 - sum
else: # y不在边界
if x == 0: # 左边非顶点
sum = img.getpixel((x, y - 1)) \
+ cur_pixel \
+ img.getpixel((x, y + 1)) \
+ img.getpixel((x + 1, y - 1)) \
+ img.getpixel((x + 1, y)) \
+ img.getpixel((x + 1, y + 1))
return 6 - sum
elif x == width - 1: # 右边非顶点
# print('%s,%s' % (x, y))
sum = img.getpixel((x, y - 1)) \
+ cur_pixel \
+ img.getpixel((x, y + 1)) \
+ img.getpixel((x - 1, y - 1)) \
+ img.getpixel((x - 1, y)) \
+ img.getpixel((x - 1, y + 1))
return 6 - sum
else: # 具备9领域条件的
sum = img.getpixel((x - 1, y - 1)) \
+ img.getpixel((x - 1, y)) \
+ img.getpixel((x - 1, y + 1)) \
+ img.getpixel((x, y - 1)) \
+ cur_pixel \
+ img.getpixel((x, y + 1)) \
+ img.getpixel((x + 1, y - 1)) \
+ img.getpixel((x + 1, y)) \
+ img.getpixel((x + 1, y + 1))
return 9 - sum
def imageNew2_border(self):
"""
获取imageNew2中 文字位置