舌体胖瘦的自动分析-曲线拟合-或许是最简单判断舌形的方案(六)

news2024/12/28 9:46:48

返回至系列文章导航博客

1 简介

在中医智能舌诊项目中需要舌体胖瘦的自动分析
舌体胖瘦是中医诊断中重要的观察依据,。胖大舌“舌色淡白,舌体胖嫩,比正常舌大而厚,甚至充满口腔”,主脾肾阳虚,气化失常,水湿内停。舌体比正常舌瘦小而薄,称为“瘦薄舌”,主气血两虚和阴血不足。中医一般通过与正常舌比较来判断舌的胖瘦。但由于年龄、性别、区域的差异,正常舌本身就没有一个大小标准,给舌体胖瘦的自动定量分析造成困难。并且由于用户上传的图像比例差异比较大,这使得舌形判断难上加难。

在进行舌体胖瘦判断应有两个前提:

(1)用户上传的舌象图片已经被分割完成;
在这里插入图片描述

(2)舌体处于“垂直状态”;
在这里插入图片描述
这两个步骤的处理方案已在之前的文章中有所介绍:
【python-Unet】计算机视觉 舌象舌头图片分割 机器学习(三)
【python】计算机视觉~舌象图片中舌体倾斜判别(四)

下面我们来详细讲解如何让计算机智能判别用户上传的舌象胖瘦!

2 原理讲解——多项式曲线拟合

2.1 舌体曲线拟合参数与形状的关系

通过对舌体轮廓进行曲线拟合,可以用较少的参数表示舌体轮廓。对舌前部轮廓采用4次多项式拟合
在这里插入图片描述

发现曲线拟合参数与曲线形状的尖锐与圆钝有以下关系:
(1)由于舌体接近对称,因此奇次项系数一般相对较小,对舌体形状的影响较小,而常数项根本不影响曲线的形状。
(2)舌体的总体形状趋势取决于其最高项——四次项,在其他各项系数相同的情况下,四次项系数越大,曲线越尖锐;越小,曲线越圆钝。
(3)尖锐和圆钝的程度不但与四次项和二次项的符号关系有关,还与两个系数的绝对值关系有关。二次项与四次项系数绝对值之比越大,曲线的尖锐与圆钝越显著。
在这里插入图片描述

2.2 胖瘦指数定义

通过上述函数图像的特点总结胖瘦指数。
胖瘦指数与四次项系数绝对值成反比,并且与二次项系数和四次项系数的符号关系和绝对值之比有关。胖瘦指数越大,舌体越胖。根据胖瘦特征已知的舌图像样本确定分级标准,可以将舌体描述为“胖”、“不胖不瘦”、“瘦”3种类型。
在这里插入图片描述
其中a4为四次项系数,a2为二次项系数。

3 具体实现过程

首先是要将舌象图片进行舌体分割(参照【python-Unet】计算机视觉 舌象舌头图片分割 机器学习(三))
在这里插入图片描述

舌体胖瘦分析的主要的对象是中下舌位,上舌位会影响分析的准确性,因此取舌体轮廓标记点的下0.75舌位。示意图如下图所示:
在这里插入图片描述

对下0.75舌位标记像素点进行舌体轮廓的多项式曲线拟合。由于分析的是曲线的“胖瘦”,因此多项式曲线的奇数次项影响较小,且项数较大较好。权衡模型的运行效率,中e诊采用4次项多项式曲线拟合。进行多张图片拟合的确定系数(R-square=SSR/SST)为0.82~0.95,说明4次多项式曲线拟合效果较好。舌体轮廓4次多项式拟合示意图如下:
在这里插入图片描述
将得到4次多项式拟合曲线系数代入如下公式,计算胖瘦指数。通过胖瘦指数来判断用户舌体的胖瘦。
在这里插入图片描述
其中a4为四次项系数,a2为二次项系数。
胖瘦值数越大说明舌体越宽大,胖瘦指数越小说明舌体越瘦小;胖瘦指数位于4.3-7.8范围内是正常舌,小于4.3是瘦小舌,大于7.8是肥大舌。
注:这里的数据可能准确度并不高,应当在大量样本数据验证后得出结论,需要后面继续验证!

4 代码实现

注:此后的代码是在已经分割好舌象以及舌体倾斜判断后,其中代码参照前文!

4.1 contour_to.py

from PIL import Image
import numpy as np

def contour_to(in_path=r"result\blend.png", out_path=r"result\inline.png"):
    """
    将分隔好的图像数据进行描点
    in_path为绿底+原图图片
    put_path为黑底+白点图片
    返回对称轴坐标以及轮廓坐标
    """
    img_before = Image.open(in_path)
    img_before_array = np.array(img_before)  #把图像转成数组格式img = np.asarray(image)

    shape_before = img_before_array.shape
    
    height = shape_before[0]
    width = shape_before[1]
    dst = np.zeros((height,width,3))
    
    wire = []
    axle_wire = []
    outcome_wire = []
    

    for h in range(0,height):
        lis = []
        h_all = 0
        w_all = 0
        for w in range (0,width-1):
            (b1,g1,r1) = img_before_array[h,w]
            (b2,g2,r2) = img_before_array[h,w+1]
            if (b1, g1, r1) == (1,204,182) and (b2,g2,r2) != (1,204,182): 
                dst[h, w] = (255,255,255)
                lis.append((h,w))
                outcome_wire.append((h,w))
            elif (b1, g1, r1) != (1,204,182) and (b2,g2,r2) == (1,204,182):
                dst[h, w+1] = (255,255,255)
                lis.append((h,w+1))
                outcome_wire.append((h,w+1))
            else:
                pass

        if len(lis) == 0:
            pass
        else:
            for i in lis:
                h_all += i[0]
                w_all += i[1]
            h_avg = h_all//len(lis)
            w_avg = w_all//len(lis)
            dst[h_avg, w_avg] = (255,255,255)
            axle_wire.append((h_avg, w_avg))

    img2 = Image.fromarray(np.uint8(dst))
    img2.save(out_path,"png")
    
    wire.append(axle_wire)
    wire.append(outcome_wire)
    
    return wire

4.2 outline_cut.py

import numpy as np 
from PIL import Image

def outline_cut(outcome_wire):
    """
    截取轮廓下1/4像素点
    """
    save = outcome_wire
    pool = []
    for i in outcome_wire:
        pool.append(i[0])
    pool.sort()
    judge = pool[int(1 + (float(len(pool)) - 1) * 1 / 4)]
    
    

    del_data = 0
    for i in range(len(outcome_wire)):
        if outcome_wire[i][0] < judge:
            del_data = i
        else:
            pass

    del save[0:del_data]
    
    height = 256
    width = 256
    dst = np.zeros((height,width,3))
    for i in outcome_wire:
        h = i[0]
        w = i[1]
        dst[h,w] = (255,255,255)
    img2 = Image.fromarray(np.uint8(dst))
    img2.save(r"result\0.5cuted.png","png")
    
    return save

4.3 linger.py

import matplotlib.pyplot as plt
import numpy as np
from sklearn import  linear_model
#导入线性模型和多项式特征构造模块
from sklearn.preprocessing import  PolynomialFeatures

def linger(wire):
    a1, a2 = zip(*wire)
    x = list(a2)
    y = list(map(lambda i: i * -1, a1))
    datasets_X = x
    datasets_Y = y

    #求得datasets_X的长度,即为数据的总数。
    length =len(datasets_X)
    #将datasets_X转化为数组, 并变为二维,以符合线性回 归拟合函数输入参数要求
    datasets_X= np.array(datasets_X).reshape([length,1])
    #将datasets_Y转化为数组
    datasets_Y=np.array(datasets_Y)

    minX =min(datasets_X)
    maxX =max(datasets_X)
    #以数据datasets_X的最大值和最小值为范围,建立等差数列,方便后续画图。
    X=np.arange(minX,maxX).reshape([-1,1])
    #degree=4表示建立datasets_X的四次多项式特征X_poly。
    poly_reg =PolynomialFeatures(degree=4)
    X_ploy =poly_reg.fit_transform(datasets_X)
    lin_reg_2=linear_model.LinearRegression()
    lin_reg_2.fit(X_ploy,datasets_Y)

    #查看回归方程系数
    #print('Cofficients:',lin_reg_2.coef_)
    #查看回归方程截距
    #print('intercept',lin_reg_2.intercept_)
    plt.scatter(datasets_X,datasets_Y,color='red')
    plt.plot(X,lin_reg_2.predict(poly_reg.fit_transform(X)),color='blue')
    plt.xlabel('x')
    plt.ylabel('y')
    plt.show()
    return lin_reg_2.coef_

4.4 调用总函数

coefficient = linger.linger(contour_to.outline_cut(contour_to()[1]))
print(coefficient)

后根据coefficient中的多项式系数代入如下公式判断舌体胖瘦:
在这里插入图片描述

舌体判别算法至此结束

在这里插入图片描述
总的来讲就是:
step1:舌象图片自适应调节
step2:舌体分割
step3:舌体倾斜判断
step4:曲线拟合判断舌形

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/421797.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++无符号整型与有符号整型变量的运算-不简单

示例分析&#xff1a; #include<iostream> #include <stdio.h>struct Result {char c;char d;unsigned char e; };Result getChar(int x, int y) {Result res;unsigned int a x;(a y > 10) ? (res.c 1) : (res.c 2);res.d a y;res.e a y;return res; …

RHCE第一次作业at和cront两个任务管理程序的区别

1.at 单一执行的例行性工作&#xff1a;仅处理执行一次就结束了 -m 当任务完成之后&#xff0c;即使没有标准输出&#xff0c;将给用户发送邮件 -l atq的别名&#xff0c;可列出目前系统上面的所有该用户的at调度 -d atrm的别名,可以取消一个在at调度中的工作 -v 使用较明显的…

基于html+css的图片展示11

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

信息安全保障人员CISAW认证基础级、专业级通用认证条件

信息安全保障人员认证&#xff08;Certified Information Security Assurance Worker&#xff0c;简称“CISAW”&#xff09;是中国网络安全审查技术与认证中心针对信息安全保障领域不同专业技术方向、应用方向和保障岗位&#xff0c;依据国际标准ISO/IEC 17024《人员认证机构通…

HTTPS-TSL握手

HTTP一般基于TCP协议&#xff0c;而HTTPS就是在这之间加了SSL/TLS协议&#xff0c;那么在TCP三次握手建立TCP连接后&#xff0c;就需要TLS握手建立SSL/TLS连接。 TLS握手-流程 &#xff08;基于RSA算法&#xff09; &#xff08;1&#xff09;首先&#xff0c;客户端向服务器发…

Unity快手上手【熟悉unity编辑器,C#脚本控制组件一些属性之类的】

Unity学习参考文档和开发工具 ☺ unity的官网文档&#xff1a;https://docs.unity3d.com/cn/current/Manual/ScriptingSection.html ■ 学习方式&#xff1a; 首先了解unity相关概述&#xff0c;快速认识unity编辑器&#xff0c;然后抓住重点的学&#xff1a;游戏对象、组件|…

【C++】1. 命名空间

文章目录一、命名空间的由来二、命名空间的使用2.1 关键字&#xff1a;namespace2.2 访问命名空间里的标识符2.3 命名空间的特点三、总结一、命名空间的由来 当我们使用c语言编写项目时&#xff0c;可能遇到以下情况&#xff1a; 变量名与某个库函数名重复&#xff0c;导致保…

sscanf和snprintf格式化时间字符串的日期与时间戳相互转换用法

sscanf格式化时间字符串的用法 UTC&#xff1a;Coordinated Universal Time 协调世界时。因为地球自转越来越慢&#xff0c;每年都会比前一年多出零点几秒&#xff0c;每隔几年协调世界时组织都会给世界时1秒&#xff0c;让基于原子钟的世界时和基于天文学&#xff08;人类感知…

测试技术与信号处理实验报告

目录 金属箔式应变片——单臂电桥性能实验 金属箔式应变片——半桥性能实验 金属箔式应变片——全桥性能实验 差动变压器的性能实验 直流全桥的应用——电子秤实验 交流激励时霍尔式传感器的位移特性实验 电容式传感器的位移实验 磁电式转速传感器测速实验 金属箔式应变…

C++ -- 继承

文章目录1. 继承的概念和定义1.1 概念1.2 定义1.2.1 定义格式1.2.2 继承基类成员访问方式的变化2. 基类和派生类对象赋值转换3. 继承中的作用域4. 派生类的默认成员函数5. 继承与友元6. 继承与静态成员7. 复杂的菱形继承及菱形虚拟继承8. 继承和组合1. 继承的概念和定义 1.1 概…

听歌无线耳机哪个品牌好?2023适合听歌的好音质蓝牙耳机推荐

现如今&#xff0c;不管是听歌、追剧或是玩游戏&#xff0c;不少人喜欢戴蓝牙耳机进行。因为蓝牙耳机的功能更丰富&#xff0c;连接方便&#xff0c;还摆脱了线的束缚&#xff0c;使用起来更方便。那么&#xff0c;听歌无线耳机哪个品牌好&#xff1f;针对这个问题&#xff0c;…

『造轮子』亿级短URL生成器的架构设计及源码分享

&#x1f4e3;读完这篇文章里你能收获到 了解博主的短链生成的架构设计思路学习不同的短链技术方案选择学习基于混淆的自增短URL算法了解博主造的轮子SuperShortLink短链开源项目感谢点赞收藏&#xff0c;避免下次找不到~ 文章目录一、需求分析1. 短链生成及访问需求2. 短链应…

Python+requests+unittest+excel接口自动化测试框架

一、框架结构&#xff1a; 工程目录 二、Case文件设计 三、基础包 base 3.1 封装get/post请求&#xff08;runmethon.py&#xff09; 1 import requests2 import json3 class RunMethod:4 def post_main(self,url,data,headerNone):5 res None6 if heade…

互联网医院源码|搭建互联网医院系统时运营需要哪些资质?

目前一线城市已经都有完善的医疗系统&#xff0c;人们对于线上问诊系统越来越熟悉&#xff0c;使用的人也越来越多&#xff0c;对于一些偏远的地区来说在线问诊平台有着更广泛的应用和意义&#xff0c;互联网医院开发实现了医疗资源共享的情况&#xff0c;打破了地域限制&#…

文献管理软件Endnote、Mendeley、Zotero比较及选择,Zotero基础使用技巧

引言 大家好&#xff0c;我是比特桃。日常开发的项目分为两种&#xff0c;一种是成熟化的工程项目&#xff0c;只需要与具体的业务紧密结合及应用&#xff0c;难点也比较偏向于软件工程或者互联网高并发的方向。这种项目我们通常不会选择去查文献去寻找问题的解决办法&#xf…

微信小程序开发 | 音乐小程序项目

音乐小程序项目3.1 开发前的准备3.1.1 项目展示3.1.2 项目分析3.1.3 项目初始化3.2 【任务1】标签页切换3.2.1 任务分析3.2.2 前导知识3.2.3 编写页面结构和样式3.2.4 实现标签页切换3.3 【任务2】音乐推荐3.3.1 任务分析3.3.2 前导知识3.3.3 内容区域滚动3.3.4 轮播图3.3.5 功…

15-721 chapter2 内存数据库

Background 随着时代的发展&#xff0c;DRAM可以容纳足够的便宜&#xff0c;容量也变大了。对于数据库来说&#xff0c;数据完全可以fit in memory&#xff0c;但同时面向disk的数据库架构不能很好的发挥这个特性 这张图是disk database的cpu instruction cost 想buffer pool…

使用PyG(PyTorch Geometric)实现基于图卷积神经网络(GCN)的节点分类任务

文章目录基本介绍PyTorch Geometric图卷积神经网络GCN节点分类任务实现Cora数据集搭建GCN模型训练与测试迭代并输出完整代码基本介绍 PyTorch Geometric PyG&#xff08;PyTorch Geometric&#xff09;是一个基于PyTorch的库&#xff0c;可以轻松编写和训练图神经网络&#x…

ChatGPT,开启人机交互新篇章

ChatGPT在世界掀起了生成式AI的热潮&#xff0c;2个月实现月活用户过亿&#xff0c;是人类有史以来突破1亿人用户最快的消费端互联网产品&#xff0c;打破了Tiktok9个月破亿用户的纪录。不少专家将其视为第四次工业革命&#xff0c;资本市场也贡献大量涨停。当第一波的热情消退…

Android 7.1 Toast修复之终极篇,进程不奔溃(包含apk和兼容外来dex插件)

修复android 7.1 Toast的篇章&#xff1a; 常规app通过ams lancet 字节编码处理&#xff1a;Android Lancet Aop 字节编码修复7.1系统Toast问题(WindowManager$BadTokenException)多渠道游戏app兼容性处理:Android 7.1 Toast修复之多渠道包动态使用Booster或者Lancet plugin …