物理超好玩

  • 首页
  • 书法字典APP下载
  • 资源列表
  • 关于
反游戏沉迷
真诚面对自己
  1. 首页
  2. 程序设计
  3. 正文

用OpenCV的K-Means聚类对书法作品进行单字分割

2021年01月24日 1256点热度 5人点赞 0条评论

文本目录

  • 用OpenCV的K-Means聚类对书法作品进行单字分割
    • 在OpenCV中K-Means函数的使用方法
    • 程序运行过程
    • 程序代码
    • 效果分析

用OpenCV的K-Means聚类对书法作品进行单字分割

对书法作品的单字进行分割,是为书法字典APP提供字模的智能化方法。较传统的方法是运用直方图进行分割。在OpenCV中有轮廓查找(findContours)和聚类(kmeans)两个处理函数。理论上选对书法作品进行轮廓查找,再将距离相近的轮廓运进行聚类,每个类就是一个汉字。

在OpenCV中K-Means函数的使用方法

关于K-Means函数的介绍可以观看:理解K-Means聚类

函数原型:

retval, bestLabels, centers = kmeans(data, K, bestLabels, criteria, attempts, flags, centers=None)

函数参数:

data:  需要分类数据,最好是np.float32的数据,每个特征放一列。

K:  聚类个数

bestLabels:预设的分类标签或者None

criteria:迭代停止的模式选择,这是一个含有三个元素的元组型数。格式为(type, max_iter, epsilon) 其中,type有如下模式:

  • cv2.TERM_CRITERIA_EPS :精确度(误差)满足epsilon,则停止。
  • cv2.TERM_CRITERIA_MAX_ITER:迭代次数超过max_iter,则停止。
  • cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER:两者结合,满足任意一个结束。

attempts:重复试验kmeans算法次数,将会返回最好的一次结果

flags:初始中心选择,可选以下两种:

  • v2.KMEANS_PP_CENTERS:使用kmeans++算法的中心初始化算法,即初始中心的选择使眼色相差最大.详细可查阅kmeans++算法。(Use kmeans++ center initialization by Arthur and Vassilvitskii)
  • cv2.KMEANS_RANDOM_CENTERS:每次随机选择初始中心(Select random initial centers in each attempt.)

返回值:

compactness:紧密度,返回每个点到相应重心的距离的平方和

labels:结果标记,每个成员被标记为分组的序号,如 0,1,2,3,4...等

centers:由聚类的中心组成的数组

程序运行过程

  1. 确定要分割的汉字数量,即聚类个数
  2. 轮廓查找生成数据
  3. 定义停止条件
  4. K-Means分类
  5. 每个聚类的轮廓到一个列表中
  6. 聚类描边

程序代码

import numpy as np
import cv2 as cv

img = cv.imread('jk.jpg')

# 要分的聚类数
sampleCount = 50
# 要分割的字符数
charCount = 50

# 转换为灰度图
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# 二值化
ret, thresh = cv.threshold(gray, 127, 255, 0)

# 反色,查找轮廓的要求是黑底白字
cv.bitwise_not(thresh, thresh)

# 发现轮廓
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

# 计算所有轮廓的面积和
pointCount = 0
for cnt in contours:
    pointCount += cv.contourArea(cnt)
# 最小面积,小于这个面积的轮廓将被删除
minPointSize = pointCount / charCount / 50

# 删除较小的轮廓
ucontours = []
for cnt in contours:
    if cv.contourArea(cnt) > minPointSize:
        ucontours.append(cnt)

cc = len(ucontours)
# 由每个轮廓的中心点生成二维数据
points = np.zeros((cc, 2), dtype=np.int)
p = 0
for cnt in ucontours:
    # 获取轮廓坐标和宽高
    x, y, w, h = cv.boundingRect(cnt)
    points[p][0] = x + w / 2
    points[p][1] = y + h / 2
    p += 1

# 转化为float数据
Z = np.float32(points)

# 定义
criteria = (cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
ret, labels, centers = cv.kmeans(Z, sampleCount, None, criteria, 10000, cv.KMEANS_PP_CENTERS)

print(ret)

# 将每个聚类的轮廓添加到同个列表中
cntlist = []
for i in range(sampleCount):
    cntlist.append([])
p = 0
for lb in labels:
    cntlist[lb[0]].append(ucontours[p])
    p += 1

rc = 255
bc = 0
# 轮廓描边
for i in range(sampleCount):
    cv.drawContours(img, cntlist[i], -1, (rc, bc, 0), 3)
    rc -= 5
    bc += 5

cv.imwrite('jkkm.png', img)

#cv.imshow('candy', img)
#cv.waitKey()



效果分析

从上图中可以看到,大多数字都准确的分割出来了,也有几处错误。如果能结合对图片进行膨胀,手动确定聚类中心,也许会更好些。

 

 

 

 

相关文章:

  1. 利用JavaCV+OpenCV的ANN_MLP神经网络训练识别MNIST手写数字
  2. 格式混乱的百度文库复制文本格式化工具
  3. 用Python下载PHET互动仿真程序
  4. 在JavaCV中合并两个Mat
  5. IDEA用Gradle打包GUI Form为可执行的jar
  6. U盘随身便携Git http服务器

订阅号“物理超好玩”
标签: K-Means OpenCV 书法作品 分割 聚类
最后更新:2021年01月24日

反游戏沉迷

真诚的面对自己的内心。 确立志向;认清游戏危害;加强户外活动。 尊重自我,做自己最擅长的事情,做自己最喜欢的事情。

点赞
< 上一篇
下一篇 >

反游戏沉迷

真诚的面对自己的内心。 确立志向;认清游戏危害;加强户外活动。 尊重自我,做自己最擅长的事情,做自己最喜欢的事情。

分类
  • NOIP (1)
  • 习题讲解 (9)
  • 克服沉迷 (2)
  • 游戏危害 (1)
  • 程序设计 (10)
  • 软件作品 (2)
标签聚合
串联电路 gradle Idea 计算题 电学 百度文库 javacv 初中物理
最新 热点 随机
最新 热点 随机
中国游戏防沉迷简史 转移注意力 认识游戏的危害 U盘随身便携Git http服务器 IDEA用Gradle打包GUI Form为可执行的jar 运用浮力求密度解题思路
运用浮力求密度解题思路 认识游戏的危害 IDEA用Gradle打包GUI Form为可执行的jar 初中物理识别电路图、画电路图的方法 已知两组数据列方程组解题补充习题 Idea中用gradle打包可执行的jar
  • 用OpenCV的K-Means聚类对书法作品进行单字分割
    • 在OpenCV中K-Means函数的使用方法
    • 程序运行过程
    • 程序代码
    • 效果分析

COPYRIGHT © 2021 反游戏沉迷. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

豫ICP备16037997号-2