opencv3+python3.5成语填字游戏(一)印刷体汉字的分割

2023-11-09

   首先这是一个成语填字游戏,大概就是一张成语填字游戏图片,通过opencv图像识别后转为矩阵,再通过解算法,解出答案,在显示到图片上。

   源代码:https://github.com/mayue801/crossword-puzzle--idiom


   本文采用投影分割法对印刷体汉字进行分割。

   投影分割是先水平方向投影,在竖直方向投影,或者先竖直方向再水平方向投影。本文选用先竖直,再水平。

   1.竖直投影。


 ------------

----------------

代码:

#针对的是印刷版的汉字,所以采用了投影法分割
#此函数是行分割,结果是一行文字
def YShadow(path):
    img  = cv2.imread(path)   #原图像
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #灰度图像
    height,width = img.shape[:2]
    
    #blur = cv2.GaussianBlur(gray,(5,5),0) #高斯模糊
    
    blur = cv2.blur(gray,(8,8)) #均值模糊
    thresh = cv2.adaptiveThreshold(blur,255,1,1,11,2)  #自适应阈值分割
    temp = thresh
    
    if(width > 500 and height > 400): #图像字体较小时,需要进行膨胀操作
        kernel = np.ones((5,5),np.uint8) #卷积核
        dilation = cv2.dilate(thresh,kernel,iterations = 1) #膨胀操作使得单个文字图像被黑像素填充
        temp = dilation
    
    '''
    cv2.imshow('image',temp)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    '''
    
    perPixelValue = 1 #每个像素的值
    projectValArry = np.zeros(width, np.int8) #创建一个用于储存每列黑色像素个数的数组


    for i in range(0,height):
        for j in range(0,width):
            perPixelValue = temp[i,j]
            if (perPixelValue == 255): #如果是黑字,对应位置的值+1
                projectValArry[i] += 1
       # print(projectValArry[i])
            
    canvas = np.zeros((height,width), dtype="uint8")
    
    for i in range(0,height):
        for j in range(0,width):
            perPixelValue = 255 #白色背景
            canvas[i, j] = perPixelValue
   

    for i in range(0,height):
        for j in range(0,projectValArry[i]):
            perPixelValue = 0 #黑色直方图投影
            canvas[i, width-j-1] = perPixelValue
    '''
    cv2.imshow('canvas',canvas)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    '''
    
    list = []
    startIndex = 0 #记录进入字符区的索引  
    endIndex = 0 #记录进入空白区域的索引  
    inBlock = 0 #是否遍历到了字符区内  


    for i in range(height):
        if (inBlock == 0 and projectValArry[i] != 0): #进入字符区
            inBlock = 1  
            startIndex = i
        elif (inBlock == 1 and projectValArry[i] == 0):#进入空白区
            endIndex = i
            inBlock = 0
            subImg = gray[startIndex:endIndex+1,0:width] #将对应字的图片截取下来
            #print(startIndex,endIndex+1)
            list.append(subImg)#添加这个字图像到list
    #print(len(list))
    return list
   2.水平投影

 ------------------------

------------------

#对行字进行单个字的分割
def XShadow(path):
    img  = cv2.imread(path)       
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    height,width = img.shape[:2]
   # print(height,width)
    #blur = cv2.GaussianBlur(gray,(5,5),0)
    
    blur = cv2.blur(gray,(8,8))
    thresh = cv2.adaptiveThreshold(blur,255,1,1,11,2) 
    
    if(width > 500):
        kernel = np.ones((4, 4),np.uint8) #卷积核
    else:
        kernel = np.ones((2, 2),np.uint8) #卷积核
    dilation = cv2.dilate(thresh,kernel,iterations = 1) #膨胀操作使得单个文字图像被黑像素填充
    
    '''
    cv2.imshow('image',thresh)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    '''
    
    perPixelValue = 1 #每个像素的值
    projectValArry = np.zeros(width, np.int8) #创建一个用于储存每列黑色像素个数的数组


    for i in range(0,width):
        for j in range(0,height):
            perPixelValue = dilation[j,i]
            if (perPixelValue == 255): #如果是黑字
                projectValArry[i] += 1
       # print(projectValArry[i])
            
    canvas = np.zeros((height,width), dtype="uint8")
    
    for i in range(0,width):
        for j in range(0,height):
            perPixelValue = 255 #白色背景
            canvas[j, i] = perPixelValue
   

    for i in range(0,width):
        for j in range(0,projectValArry[i]):
            perPixelValue = 0 #黑色直方图投影
            canvas[height-j-1, i] = perPixelValue
    '''
    cv2.imshow('canvas',canvas)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    '''
    
    list = []
    startIndex = 0 #记录进入字符区的索引  
    endIndex = 0 #记录进入空白区域的索引  
    inBlock = 0 #是否遍历到了字符区内  


    for i in range(width):
        if (inBlock == 0 and projectValArry[i] != 0): #进入字符区
            inBlock = 1  
            startIndex = i
        elif (inBlock == 1 and projectValArry[i] == 0): #进入投影区
            endIndex = i
            inBlock = 0
            #subImg = gray[0:height, startIndex:endIndex+1] #endIndex+1
            #print(startIndex,endIndex+1)
            list.append([startIndex, 0, endIndex-startIndex-1, height])
    #print(len(list))
    return list

   分割完后,将对应图片样本存储到对应文件夹,每个字共10种样本

   将这些样本及标记保存后,分别加载到samples.npy, label.npy中。供后续的机器学习算法训练使用。

   下篇讲解填字图片汉字的提取与机器学习算法训练样本,识别汉字的过程。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

opencv3+python3.5成语填字游戏(一)印刷体汉字的分割 的相关文章

随机推荐

  • 数据统计(基于文件输入输出)

    输入一些整数 求出它们的最大值 最小值 平均值 保留三位小数 输入保证这些数都是不超过1000的整数 样例输入 2 8 3 5 1 7 3 6 样例输出 1 8 4 375 基于文件重定向 define LOCAL 作用 仅在本机使用重定向
  • 小程序报错:{“errMsg”:“navigateTo:fail can not navigateTo a tabbar page”}

    小程序报错 errMsg navigateTo fail can not navigateTo a tabbar page 错误显示 VM791 1 Error MiniProgramError errMsg navigateTo fail
  • 验证码报错 java.desktop/sun.awt.FontConfiguration.getVersion(FontConfiguration.java: 问题解决

    验证码报错 org springframework web util NestedServletException Handler dispatch failed nested exception is java lang Internal
  • 【C语言】选择排序

    一 算法描述 在一遍遍历中将最小的数排到前面 几次遍历后前面就是排号序的 经过n 1次遍历 二 选择排序代码 void select int a int n int i j min temp for i 0 i
  • 矩阵和向量的乘法顺序

    矩阵和向量的乘法顺序 似乎经常有人被这个问题转晕 向量有两种表达形式 行向量和列向量 对应的矩阵也有行矩阵和列矩阵 采用哪种形式和左右手系无关 行矩阵 三个轴向量为前三行 最后一行为位移变换 连乘时从左到右接合 左边的变换先应用 变换向量时
  • Ubuntu 18.02编译opencv

    https blog csdn net public669 article details 99044895 spm 1001 2014 3001 5506 https blog csdn net Mr robot strange arti
  • 利用STM32CubeMX软件生成USB_HOST读写U盘

    一 测试平台 MCU STM32F429IGT6 工具 STM32CubeMX软件 编译软件 MDK 二 配置步骤 1 打开STM32CubeMX软件 创建新的工程文件 点击ACCESS TO MCU SELECTOR选项 2 选择芯片型号
  • 1-4、Lua基本语法

    1 4 Lua基本语法 文章目录 1 4 Lua基本语法 1 赋值语句 2 局部变量与代码块 3 控制结构语句 if语句 while语句 for语句有两大类 Lua像C和PASCAL几乎支持所有的传统语句 赋值语句 控制结构语句 函数调用等
  • MFC之图标(标题)的动态使用15

    1 图标 标题 的动态使用 我们将实现左上角动态图标的显示 首先按照向导创建新的项目 由于我们的图标是属于框架 所以在框架类处理 1 首先在框架类定义图标数组用于存储图片 我这里有四张所以大小为4 private HICON m icon
  • 程序员35岁以后就没有出路了吗?听听京东10年测开的分析

    国内的互联网行业发展较快 所以造成了技术研发类员工工作强度比较大 同时技术的快速更新又需要员工不断的学习新的技术 因此淘汰率也比较高 超过35岁的基层研发类员工 往往因为家庭原因 身体原因 比较难以跟得上工作节奏 所以裁员往往优先考虑这类员
  • MCU接收串口字符型数据转换成数据型数据

    转自 http blog csdn net langaopeng article details 7672252 做MCU开发时 常常碰到串口接收的数据是字符型数据 是ASCII码 而我们需要解析的是数据型的 如 串口接收到的是 236 8
  • 【机器学习实战】1、机器学习主要任务

    文章目录 1 1 何谓机器学习 1 2 机器学习重要性 1 3 机器学习主要任务 1 4 如何选择合适的算法 1 5 开发机器学习应用程序的步骤 1 6 python语言的优势 1 6 1 python语言特色 1 6 2 python语言
  • npm、cnpm、yarn之间的区别

    npm 在使用 npm 安装包的时候 给人的第一感觉就是慢 而且还会在命令行打印出一堆的东西 而且经常会出现 在我的电脑上可以 这个问题 着实是有点难受 但也不得不说 npm 是 node 如此成功的主要原因之一 npm的缺点如下 1 由于
  • 网站html保存,如何保存网页内容(高级篇)

    上一篇介绍了允许 另存为 的网站保存网页的方法 本篇继续介绍禁止 另存为 的网站也实现保存网页的方法 步骤比上一篇麻烦一些 但也不难 以下是具体步骤 提示 对于这类网站 尽管 文件 菜单中的 另存为 是可用的 但当你试图另存为 网页快要保存
  • [网络安全自学篇] 七十八.XSS跨站脚本攻击案例分享及总结(二)

    这是作者网络安全自学教程系列 主要是关于安全工具和实践操作的在线笔记 特分享出来与博友们学习 希望您喜欢 一起进步 前文分享了肖老师 Seak 的分享 介绍恶意代码与APT攻击中的武器 包括A2PT的攻击武器 普通APT组织的自研恶意代码
  • 虚拟机Parallels Desktop

    Mac上安装Windows虚拟机 Parallels Desktop 之前在Mac上安装虚拟机使用的是VMware Fusion 用起来感觉不是很流畅 很不舒服 所以今天试试号称Mac上最好的虚拟机Parallels Desktop 概述
  • 迷你气象站(雨量计,风速,风向)

    天气预报对于计划我们的日常活动很重要 农民需要信息来帮助他们计划农作物的种植和收割 航空公司需要了解当地天气状况才能安排航班 天气预报可以帮助我们做出更明智的日常决策 甚至可以帮助我们摆脱危险 在本教程中 我们将制作一个微型气象站 该气象站
  • python迷宫游戏的课程设计,Python迷宫游戏(基础版)

    画地图 map data 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 2 1 0 0 0 0 0 0 1 1 0 1 0 1 0 1 1 0 1 1 0 1 0 1 0 1 1 0 1 1 0 0 0
  • 互联网晚报

    教育部回应降低英语教学比重建议 中小学外语课时占比低于语文等学科 教育部网站9月23日公布 对 关于增强文化自信增加中国文化内容教学改革和降低英语教学比重的建议 的答复 答复显示 根据规定 外语课时占比为6 8 明显低于语文 数学 体育 艺
  • opencv3+python3.5成语填字游戏(一)印刷体汉字的分割

    首先这是一个成语填字游戏 大概就是一张成语填字游戏图片 通过opencv图像识别后转为矩阵 再通过解算法 解出答案 在显示到图片上 源代码 https github com mayue801 crossword puzzle idiom 本