Opencv:验证码图像处理

2021-11-22 18:26:12 浏览数 (1)

本篇讲的主要是对验证码图片的二值去边去线降噪。

最近天热了。人也有点疲惫,不打太多字。

首先安装 opencv :(点击链接查看)

https://blog.csdn.net/weixin_43582101/article/details/88660570

我自己画了个图(下文图片数据根据这张图写的)

图片名:1234567.png:

读入图片1234567.png

代码语言:javascript复制
import cv2
im = cv2.imread('1234567.png')

使用cvtColor方法进行颜色空间转换,转成黑白的

代码语言:javascript复制
im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)

可以保存下看看:

代码语言:javascript复制
 cv2.imwrite('33333.png',im)

然后我们先去除边框:

啥原理呢,就是把这个边框范围的 所有坐标的像素 都变成 255 白色的。这个具体要看你的图片的边框值是多少,需要你看情况。

代码语言:javascript复制
def clear_border(img):
  h, w = img.shape[:2]                          # h高、w宽
  for y in range(0, w):
    for x in range(0, h):
      if y < 50 or y > w - 61:     # 把在50以内的像素坐标[0,0]到[高,50],[0,宽-50]到[高,宽],都变白色
        img[x, y] = 255
      if x < 60 or x > h - 60:    #  如上
        img[x, y] = 255
  cv2.imwrite('22222.png',img)
  return img

看下 22222.png:

框没了。

现在我们来去除下线:也就是干扰线降噪

这个原理呢,就是来判断这个像素点旁边是不是白的,如果是说明他是干扰线,就把他也变成白的。

代码语言:javascript复制
def interference_line(img):
  h, w = img.shape[:2]
  # opencv矩阵点是反的
  # img[1,2] 1:图片的高度,2:图片的宽度
  for y in range(1, w - 1):
    for x in range(1, h - 1):
      count = 0
      if img[x, y - 1] > 245:
        count = count   1
      if img[x, y   1] > 245:
        count = count   1
      if img[x - 1, y] > 245:
        count = count   1
      if img[x   1, y] > 245:
        count = count   1
      if count > 2:
        img[x, y] = 255         #判断一圈有多少白的,超过2,就转成白的。
  cv2.imwrite('44444.png',img)
  return img

看下44444.png:

线去的差不多了。但是还有些干扰点了什么的。

点降噪:

点降噪的话可以自己看情况来写,也可以利用已经封装好的方法。

中值滤波medianBlur:

这个中值滤波 基本思想是用像素点邻域 灰度值的中值 来代替该像素点的灰度值,让周围的像素值接近真实的值从而消除孤立的噪声点。

代码语言:javascript复制
import numpy
image = cv2.imread('44444.png')
result = numpy.array(image)
ss = cv2.medianBlur(result,5)
cv2.imwrite('66666.png',ss)

看下66666.png

是不是好多了。你还可以再次调用这个方法。

高斯滤波:GaussianBlur函数:

高斯滤波 是需要对一个像素的周围的像素给予更多的重视。因此,可通过分配权重来重新计算这些周围点的值。这可通过高斯函数(钟形函数,即喇叭形数)的权重方案来解决

代码语言:javascript复制
# 将每个像素替换为该像素周围像素的均值
image1 = cv2.imread('66666.png')
result = cv2.blur(image1,(5,5))
gaussianResult = cv2.GaussianBlur(result,(5,5),1.5)
cv2.imwrite('77777.png',gaussianResult)

再看77777.png

好了,先到这吧。其实没多少东西,如果想研究下降噪的原理话,可以与我联系一起再深入学习下。

完整流程代码:

代码语言:javascript复制
import cv2
import numpy


def cvt(img):
  img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  return img

def clear_border(img):
  h, w = img.shape[:2]                          # h高、w宽
  for y in range(0, w):
    for x in range(0, h):
      if y < 50 or y > w - 61:     # 把在50以内的像素坐标[0,0]到[高,50],[0,宽-50]到[高,宽],都变白色
        img[x, y] = 255
      if x < 60 or x > h - 60:    #  如上
        img[x, y] = 255
  cv2.imwrite('22222.png',img)
  return img

def interference_line(img):
  h, w = img.shape[:2]
  # opencv矩阵点是反的
  # img[1,2] 1:图片的高度,2:图片的宽度
  for y in range(1, w - 1):
    for x in range(1, h - 1):
      count = 0
      if img[x, y - 1] > 245:
        count = count   1
      if img[x, y   1] > 245:
        count = count   1
      if img[x - 1, y] > 245:
        count = count   1
      if img[x   1, y] > 245:
        count = count   1
      if count > 2:
        img[x, y] = 255         #判断一圈都是白的,就转成白的。
  return img

def dian_medianBlur(image):
  result = numpy.array(image)
  image = cv2.medianBlur(result,5)
  return image

def dian_GaussianBlur(image):
  result = cv2.blur(image,(5,5))
  gaussianResult = cv2.GaussianBlur(result,(5,5),1.5)
  return gaussianResult

if __name__ == '__main__':
  img = cv2.imread('1234567.png')
  image = dian_GaussianBlur(dian_medianBlur(interference_line(clear_border(cvt(img)))))
  cv2.imwrite('88888.png',image)

0 人点赞