首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >cv2处理图片的模板

cv2处理图片的模板

作者头像
小小咸鱼YwY
发布于 2020-07-15 08:06:53
发布于 2020-07-15 08:06:53
42500
代码可运行
举报
文章被收录于专栏:python-爬虫python-爬虫
运行总次数:0
代码可运行
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from PIL import Image
from pytesseract import *
from fnmatch import fnmatch
from queue import Queue
import cv2
import time

import os





def clear_border(img,img_name):
  '''去除边框
  '''

  filename = './out_img/' + img_name.split('.')[0] + '-clearBorder.jpg'
  h, w = img.shape[:2]
  for y in range(0, w):
    for x in range(0, h):
      # if y ==0 or y == w -1 or y == w - 2:
      if y < 4 or y > w -4:
        img[x, y] = 255
      # if x == 0 or x == h - 1 or x == h - 2:
      if x < 4 or x > h - 4:
        img[x, y] = 255

  cv2.imwrite(filename,img)
  return img


def interference_line(img, img_name):
  '''
  干扰线降噪
  '''

  filename =  './out_img/' + img_name.split('.')[0] + '-interferenceline.jpg'
  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 > 3:
        img[x, y] = 255
  cv2.imwrite(filename,img)
  return img

def interference_point(img,img_name, x = 0, y = 0):
    """点降噪
    9邻域框,以当前点为中心的田字框,黑点个数
    :param x:
    :param y:
    :return:
    """
    filename =  './out_img/' + img_name.split('.')[0] + '-interferencePoint.jpg'
    # todo 判断图片的长宽度下限
    cur_pixel = img[x,y]# 当前像素点的值
    height,width = img.shape[:2]

    for y in range(0, width - 1):
      for x in range(0, height - 1):
        if y == 0:  # 第一行
            if x == 0:  # 左上顶点,4邻域
                # 中心点旁边3个点
                sum = int(cur_pixel) \
                      + int(img[x, y + 1]) \
                      + int(img[x + 1, y]) \
                      + int(img[x + 1, y + 1])
                if sum <= 2 * 245:
                  img[x, y] = 0
            elif x == height - 1:  # 右上顶点
                sum = int(cur_pixel) \
                      + int(img[x, y + 1]) \
                      + int(img[x - 1, y]) \
                      + int(img[x - 1, y + 1])
                if sum <= 2 * 245:
                  img[x, y] = 0
            else:  # 最上非顶点,6邻域
                sum = int(img[x - 1, y]) \
                      + int(img[x - 1, y + 1]) \
                      + int(cur_pixel) \
                      + int(img[x, y + 1]) \
                      + int(img[x + 1, y]) \
                      + int(img[x + 1, y + 1])
                if sum <= 3 * 245:
                  img[x, y] = 0
        elif y == width - 1:  # 最下面一行
            if x == 0:  # 左下顶点
                # 中心点旁边3个点
                sum = int(cur_pixel) \
                      + int(img[x + 1, y]) \
                      + int(img[x + 1, y - 1]) \
                      + int(img[x, y - 1])
                if sum <= 2 * 245:
                  img[x, y] = 0
            elif x == height - 1:  # 右下顶点
                sum = int(cur_pixel) \
                      + int(img[x, y - 1]) \
                      + int(img[x - 1, y]) \
                      + int(img[x - 1, y - 1])

                if sum <= 2 * 245:
                  img[x, y] = 0
            else:  # 最下非顶点,6邻域
                sum = int(cur_pixel) \
                      + int(img[x - 1, y]) \
                      + int(img[x + 1, y]) \
                      + int(img[x, y - 1]) \
                      + int(img[x - 1, y - 1]) \
                      + int(img[x + 1, y - 1])
                if sum <= 3 * 245:
                  img[x, y] = 0
        else:  # y不在边界
            if x == 0:  # 左边非顶点
                sum = int(img[x, y - 1]) \
                      + int(cur_pixel) \
                      + int(img[x, y + 1]) \
                      + int(img[x + 1, y - 1]) \
                      + int(img[x + 1, y]) \
                      + int(img[x + 1, y + 1])

                if sum <= 3 * 245:
                  img[x, y] = 0
            elif x == height - 1:  # 右边非顶点
                sum = int(img[x, y - 1]) \
                      + int(cur_pixel) \
                      + int(img[x, y + 1]) \
                      + int(img[x - 1, y - 1]) \
                      + int(img[x - 1, y]) \
                      + int(img[x - 1, y + 1])

                if sum <= 3 * 245:
                  img[x, y] = 0
            else:  # 具备9领域条件的
                sum = int(img[x - 1, y - 1]) \
                      + int(img[x - 1, y]) \
                      + int(img[x - 1, y + 1]) \
                      + int(img[x, y - 1]) \
                      + int(cur_pixel) \
                      + int(img[x, y + 1]) \
                      + int(img[x + 1, y - 1]) \
                      + int(img[x + 1, y]) \
                      + int(img[x + 1, y + 1])
                if sum <= 4 * 245:
                  img[x, y] = 0
    cv2.imwrite(filename,img)
    return img

def _get_dynamic_binary_image(filedir, img_name):
  '''
  自适应阀值二值化
  '''

  filename =   './out_img/' + img_name.split('.')[0] + '-binary.jpg'
  img_name = filedir + '/' + img_name
  print('.....' + img_name)
  im = cv2.imread(img_name)
  im = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)

  th1 = cv2.adaptiveThreshold(im, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 21, 1)
  cv2.imwrite(filename,th1)
  return th1

def _get_static_binary_image(img, threshold = 140):
  '''
  手动二值化
  '''

  img = Image.open(img)
  img = img.convert('L')
  pixdata = img.load()
  w, h = img.size
  for y in range(h):
    for x in range(w):
      if pixdata[x, y] < threshold:
        pixdata[x, y] = 0
      else:
        pixdata[x, y] = 255

  return img


def cfs(im,x_fd,y_fd):
  '''用队列和集合记录遍历过的像素坐标代替单纯递归以解决cfs访问过深问题
  '''

  # print('**********')

  xaxis=[]
  yaxis=[]
  visited =set()
  q = Queue()
  q.put((x_fd, y_fd))
  visited.add((x_fd, y_fd))
  offsets=[(1, 0), (0, 1), (-1, 0), (0, -1)]#四邻域

  while not q.empty():
      x,y=q.get()

      for xoffset,yoffset in offsets:
          x_neighbor,y_neighbor = x+xoffset,y+yoffset

          if (x_neighbor,y_neighbor) in (visited):
              continue  # 已经访问过了

          visited.add((x_neighbor, y_neighbor))

          try:
              if im[x_neighbor, y_neighbor] == 0:
                  xaxis.append(x_neighbor)
                  yaxis.append(y_neighbor)
                  q.put((x_neighbor,y_neighbor))

          except IndexError:
              pass
  # print(xaxis)
  if (len(xaxis) == 0 | len(yaxis) == 0):
    xmax = x_fd + 1
    xmin = x_fd
    ymax = y_fd + 1
    ymin = y_fd

  else:
    xmax = max(xaxis)
    xmin = min(xaxis)
    ymax = max(yaxis)
    ymin = min(yaxis)
    #ymin,ymax=sort(yaxis)

  return ymax,ymin,xmax,xmin

def detectFgPix(im,xmax):
  '''搜索区块起点
  '''

  h,w = im.shape[:2]
  for y_fd in range(xmax+1,w):
      for x_fd in range(h):
          if im[x_fd,y_fd] == 0:
              return x_fd,y_fd

def CFS(im):
  '''切割字符位置
  '''

  zoneL=[]#各区块长度L列表
  zoneWB=[]#各区块的X[起始,终点]列表
  zoneHB=[]#各区块的Y[起始,终点]列表

  xmax=0#上一区块结束黑点横坐标,这里是初始化
  for i in range(10):

      try:
          x_fd,y_fd = detectFgPix(im,xmax)
          # print(y_fd,x_fd)
          xmax,xmin,ymax,ymin=cfs(im,x_fd,y_fd)
          L = xmax - xmin
          H = ymax - ymin
          zoneL.append(L)
          zoneWB.append([xmin,xmax])
          zoneHB.append([ymin,ymax])

      except TypeError:
          return zoneL,zoneWB,zoneHB

  return zoneL,zoneWB,zoneHB


def cutting_img(im,im_position,img,xoffset = 1,yoffset = 1):
  filename =  './out_img/' + img.split('.')[0]
  # 识别出的字符个数
  im_number = len(im_position[1])
  # 切割字符
  for i in range(im_number):
    im_start_X = im_position[1][i][0] - xoffset
    im_end_X = im_position[1][i][1] + xoffset
    im_start_Y = im_position[2][i][0] - yoffset
    im_end_Y = im_position[2][i][1] + yoffset
    cropped = im[im_start_Y:im_end_Y, im_start_X:im_end_X]
    cv2.imwrite(filename + '-cutting-' + str(i) + '.jpg',cropped)



def main():
  filedir = './easy_img'

  for file in os.listdir(filedir):
    if fnmatch(file, '*.png'):
      img_name = file

      # 自适应阈值二值化
      im = _get_dynamic_binary_image(filedir, img_name)

      # 去除边框
      im = clear_border(im,img_name)

      # 对图片进行干扰线降噪
      im = interference_line(im,img_name)

      # 对图片进行点降噪
      im = interference_point(im,img_name)

      # 切割的位置
      im_position = CFS(im)

      maxL = max(im_position[0])
      minL = min(im_position[0])

      # 如果有粘连字符,如果一个字符的长度过长就认为是粘连字符,并从中间进行切割
      if(maxL > minL + minL * 0.7):
        maxL_index = im_position[0].index(maxL)
        minL_index = im_position[0].index(minL)
        # 设置字符的宽度
        im_position[0][maxL_index] = maxL // 2
        im_position[0].insert(maxL_index + 1, maxL // 2)
        # 设置字符X[起始,终点]位置
        im_position[1][maxL_index][1] = im_position[1][maxL_index][0] + maxL // 2
        im_position[1].insert(maxL_index + 1, [im_position[1][maxL_index][1] + 1, im_position[1][maxL_index][1] + 1 + maxL // 2])
        # 设置字符的Y[起始,终点]位置
        im_position[2].insert(maxL_index + 1, im_position[2][maxL_index])

      # 切割字符,要想切得好就得配置参数,通常 1 or 2 就可以
      cutting_img(im,im_position,img_name,1,1)

      # 识别验证码
      cutting_img_num = 0
      for file in os.listdir('./out_img'):
        try:
            print(file)
            a= Image.open(f'./out_img/{file}')
            text = image_to_string(a)
            print('识别内容',text)
            print('-'*300)
        except:
            pass
if __name__ == '__main__':
  main()
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-07-13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python验证码识别
最近在做爬虫的时候发现手动输入验证码算是比较烦了,就网上搜了一下,结果发现真的有现成的,作者:老板丶鱼丸粗面,写的很完整,看一下。所有源码点击阅读原文。
我被狗咬了
2019/09/23
3K0
Python验证码识别
强智教务系统验证码识别 OpenCV
首先使用代码切割验证码,挑选出切割的比较好的验证码,制作比对库 由于使用matchTemplate函数,要求待匹配图必须比库图小,于是需要放大库图边界
WindRunnerMax
2020/08/27
5730
目标检测图像数据增强(Data Augmentation)—— 旋转
由于业务需求,需要对部分不符合检测结果的图像进行过滤,因此需要对之前的检测项目进行优化。常见问题有如下亮点:
用户3578099
2019/08/15
1.3K0
数据集少?那就来数据增强吧?
这几天老师给了我一个任务,让我识别螺栓和法兰盘,但是老师也是够高冷的,就给我了6张图片,让我训练?让我目标检测?6张图片检测个屁啊… 不过我自己也想到了数据集增强,用opencv进行图片的翻转,平移,调节亮度啊,调节对比度等等。 有两个思路 第一个思路是,先直接增强图片,把图片弄很多张,然后再一个个的去用labelimg去标注,其实想想,这个工程量也蛮大的吧,确实很大,我在傻傻的自己标注了30张图片之后,心很累。就想有没有一种方法,我这六张图片标注好了,也生成对应的.xml文件了,直接图片和对应的标注文件一起数据集的增强,在我一番百度之后,找到了一个方法,最后经过验证,数据集正确,也可以正常的训练,这也就是我说的第二个方法。唉,心真累。两个方法都写上吧,自己也好复习。
Albert_xiong
2021/06/21
1.2K0
数据集少?那就来数据增强吧?
目标检测 - 基于 SSD: Single Shot MultiBox Detector 的人体上下半身检测
这里主要是通过将训练数据转换成 Pascal VOC 数据集格式来实现 SSD 检测人体上下半身.
AIHGF
2019/02/18
1.1K0
目标检测 - 基于 SSD: Single Shot MultiBox Detector 的人体上下半身检测
【目标检测】YOLO+DOTA:小样本检测策略
之前在使用YOLOv5跑xView数据集时,发现准确率还是非常低的。在网上冲浪时,我发现了一种小样本检测策略:那就是把大分辨率的图片分割成小块进行训练,然后再输入大图进行检测。那么本篇博文就使用DOTA数据集来验证一下这种思路是否可行。
zstar
2022/09/22
3.6K0
【目标检测】YOLO+DOTA:小样本检测策略
​零基础入门深度学习(九):目标检测之常用数据预处理与增广方法
本课程是百度官方开设的零基础入门深度学习课程,主要面向没有深度学习技术基础或者基础薄弱的同学,帮助大家在深度学习领域实现从0到1+的跨越。从本课程中,你将学习到:
用户1386409
2020/02/19
1.8K0
【目标检测】大图包括标签切分,并转换成txt格式
遥感图像比较大,通常需要切分成小块再进行训练,之前写过一篇关于大图裁切和拼接的文章【目标检测】图像裁剪/标签可视化/图像拼接处理脚本,不过当时的工作流是先将大图切分成小图,再在小图上进行标注,于是就不考虑标签变换的问题。
zstar
2023/10/09
8440
【目标检测】大图包括标签切分,并转换成txt格式
构建自动车牌识别系统
在上面的架构中,有六个模块。标记、训练、保存模型、OCR和模型管道,以及RESTful API。但是本文只详细介绍前三个模块。过程如下。首先,我们将收集图像。然后使用python GUI开发的开源软件图像标注工具对图像进行车牌或号牌的标注。然后在对图像进行标记后,我们将进行数据预处理,在TensorFlow 2中构建和训练一个深度学习目标检测模型(Inception Resnet V2)。完成目标检测模型训练过程后,使用该模型裁剪包含车牌的图像,也称为关注区域(ROI),并将该ROI传递给Python中的 Tesserac API。使用PyTesseract,我们将从图像中提取文本。最后我们将所有这些放在一起,并构建深度学习模型管道。在最后一个模块中,将使用FLASK Python创建一个Web应用程序项目。这样,我们可以将我们的应用程序发布供他人使用。
deephub
2021/04/16
2.6K0
PASCAL VOC的评估代码voc_eval.py解析
给定精度和召回率计算VOC的AP,如果use_07_metric为真,使用VOC 07 11点方法。
狼啸风云
2019/12/03
1.9K0
Object Detection-YOLOv2 Input And Output Encoding
本文主要学习在PASCAL VOC2012数据集上训练YOLOv2时的Input Encoding和Output Encoding。
YoungTimes
2022/04/28
4010
Object Detection-YOLOv2 Input And Output Encoding
8.SSD目标检测之二:制作自己的训练集
最近秋色甚好,一场大风刮散了雾霾,难得几天的好天气,周末回家在大巴上看着高速两旁夕阳照射下黄澄澄的树叶,晕车好像也好了很多。 特地周六赶回来为了周末去拍点素材,周日天气也好,去了陕师大拍了照片和视频。 说正经的,如何来制作数据集。
和蔼的zhxing
2018/12/06
6741
基于Aidlux平台的人脸关键点检测以及换脸算法
运行Aidlux中examples的自带Demo:人脸、人体、手关键点检测、头发语义分割、人像语义分割、人脸检测、图像风格迁移、句子分类等,
用户10686717
2023/08/01
3610
MaskRCNN-Benchmark(Pytorch版本)训练自己的数据以及避坑指南
首先要阅读官网说明的环境要求,千万不要一股脑直接安装,不然后面程序很有可能会报错!!!
大黄大黄大黄
2019/05/13
1.9K0
MaskRCNN-Benchmark(Pytorch版本)训练自己的数据以及避坑指南
ggplot2学习笔记之图形排列
作者:严涛 浙江大学作物遗传育种在读研究生(生物信息学方向)伪码农,R语言爱好者,爱开源
生信宝典
2018/12/18
2.5K0
ggplot2学习笔记之图形排列
R可视化:ggpubr的基本图形
GGPlot2(通常缩写为ggplot2)是一个在R语言中广泛使用的绘图包,以其灵活和强大的数据可视化功能而闻名。它基于"The Grammar of Graphics"一书的概念,允许用户通过组合不同的视觉元素来创建自定义的图形。而ggpubr是ggplot2的一个扩展包,它进一步简化了图形的创建过程,特别是对于初学者来说,提供了一种更为直观和易于理解的绘图方式。
生信学习者
2024/06/11
3200
R可视化:ggpubr的基本图形
将Cityscape转换为PASACAL VOC格式的目标检测数据集
1、将Cityscape中的json格式的标注转换为.txt格式的标签# convert cityscape dataset to pascal voc format dataset# 1. convert every cityscape image label '.json' to '.txt'import jsonimport osfrom os import listdir, getcwdfrom os.path import joinimport os.pathrootdir = 'D:\datas
狼啸风云
2020/07/14
2.7K0
Object Detection-YOLOv2 Anchor Box Clustering
Dimension Clusters是YOLOv2中使用的优化策略之一,它的主要思路是通过聚合算法,从数据集中预先得到Bounding Box的形状先验数据,从而使得模型更容易学习,并且得到更好的Object Detection结果。
YoungTimes
2022/04/28
5460
Object Detection-YOLOv2 Anchor Box Clustering
【目标检测】数据增强:YOLO官方数据增强实现/imgaug的简单使用
由于自己的数据比较少,因此想采用数据增强的方式来扩充自己的数据集,对于目标检测任务而言,除了需要改变原始图像外,还需要对目标框进行相应的变化。
zstar
2022/09/20
9.2K0
【目标检测】数据增强:YOLO官方数据增强实现/imgaug的简单使用
OpenVINO实时人脸表面3D点云提取
2019出现的一个可以在移动端实时运行的人脸3D表面提取模型-FaceMesh,被很多移动端AR应用作为底层算法实现人脸检测与人脸3D点云生成。相关的论文标题为:
OpenCV学堂
2021/05/07
1.1K0
OpenVINO实时人脸表面3D点云提取
推荐阅读
相关推荐
Python验证码识别
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档