介绍:大三上做一个医学影像识别的项目,医生在原图上用红笔标记病灶点,通过记录红色的坐标位置可以得到病灶点的外接矩形,但是后续会涉及到红圈内的面积在外接矩形下的占比问题,有些外接矩形内有多个红色标记,在使用网上的opencv的fillPoly填充效果非常不理想,还有类似python计算任意多边形方法也不理想的情况下,自己探索出的一种效果还不错的计算多圈及不规则图形的面积的算法。

医生提供的病灶标记图和原图,大部分长这样

但也有一些多圈情况

很明显,这些图片都是非常需要计算面积占比的,对样本需要筛选

通过百度,用opencv的填充来计算面积,一部分效果很差,单圈画不全,多圈都是错(用将面积计算结果上色,方便观察)

通过此算法之后,无论单圈,多圈,面积计算准确度提高许多

能较为准确的计算出不规则图形的面积

正文:算法的思想很简单,遍历图片每一列,通过色差判断是否遇到标记圈,将坐标全部记录,对每一列的坐标都进行最小行和最大行记录,确定每一列的最小和最大的坐标,然后上色(类似opencv的fillPoly的实现,但是细节有些区别),只是这样效果并不好,将图片旋转90度,再做一边,将两个图片的结果放在一起做与操作,得到结果就能很好的处理多圈的标记问题和多算面积的问题(比如上面的08-LM),

算法实现

全程只用pillow库

首先先用屏幕拾色器获取目标颜色的rgb值,我这种情况下就是(237,28,36),前期截取外接矩形也是要这一步的,颜色也一致

1 defpixel_wanted(pix):2 return pix==(237,28, 36)

每一列都设定翻转位初始为False,如果上一个像素点不是目标色,当前是目标色则开始记录,一旦不是目标色,停止检测

top_Pixel都设定为黑色(0,0,0)因为有图片最上方就是目标色,导致判定出问题,直接让最上面的像素初始化是黑色

coordinate_List记录了所有符合的点坐标

1 coordinate_List =[]2 top_Pixel =(0,0,0)3 for x inrange(im.size[0]):4 flag = False #初始化每一列翻转位为False

5 for y in range(im.size[1]):6 current_pixel =im.getpixel((x,y))7 last_pixel = im.getpixel((x,y-1)) if y>0 elsetop_Pixel8 #翻转判定

9 if pixel_wanted(current_pixel) and\10 notpixel_wanted(last_pixel):11 flag =True12 if flag and notpixel_wanted(current_pixel):13 flag =False14 if(flag):15 coordinate_List.append((x,y))

coordinate_List中的点如下图

然后就是将上面获得coordinate列表进行处理

将coordinate列表中每一列的最小坐标和最大坐标进行记录

因为每一列记录的数量并不确定(应该可以在上一步改进一下),所以需要遍历多次

首先找到第一个列出现的坐标,将它的行信息记录(行信息最小确定),

然后遍历出全部的同列的坐标,比较行坐标,如果大的就将最大的代替(行信息最大确定),用一个新的列表记录数据

1 coordinate_Min_Max_List =[]2 #找最小最大

3 for i inrange(im.size[0]):4 min=-1

5 max=-1

6 for coordinate incoordinate_List:7 if coordinate[0] ==i:8 min = coordinate[1]9 max = coordinate[1]10 break

11 for coordinate incoordinate_List:12 if coordinate[0] ==i:13 if coordinate[1]>max:14 max = coordinate[1]15 coordinate_Min_Max_List.append(min)16 coordinate_Min_Max_List.append(max)

其中要将min和max都初始化为一个坐标不存在的值比如-1,为了在下一步多圈且有空隙情况下,不会出现残影现象,如下图

上一步的最后得到一个列表,第n列的最小行和最大行分别是第2n和2n+1元素,结果中的-1,为了让下一步不会画进去

然后就是绘制图片了,每一列将列表中对应的最小行到最大行涂满

1 #上色

2 for x inrange(im.size[0]):3 for y in range(im.size[1]):4 min = coordinate_Min_Max_List[x*2]5 max = coordinate_Min_Max_List[x*2+1]6 if min

10 pass

至此,就是类似opencv的算法实现,虽然还差翻转做与操作,但是已经比opencv生成的效果好,写成函数后续调用,

然后就是简单的翻转90度,再调用一次这个函数再做一遍

1 defCal_S(im):2 im_0 =im.rotate(0)3 im_90 = im.rotate(90, expand=True)4

5 im_0 =fillPoly(im_0)6 im_90 =fillPoly(im_90)7 im_90 = im_90.rotate(-90, expand=True)8

9 i=010 for x inrange(im.size[0]):11 for y in range(im.size[1]):12 if(im_0.getpixel((x,y))==(0,255,0) and

13 im_90.getpixel((x,y))==(0,255,0)):14 im.putpixel((x,y),(0,255,0))15 i+=1

16 return i/(im.size[0]*im.size[1])

做两遍的效果图

可以看到效果非常不错,但是依旧有个别图像有问题,比如十字分布的,

但现在的话误差已经降低非常多了,这些极其个别的十字现象可以手动把原图切割一下,或者干脆不处理了

所有代码,画出绿图片为了方便直观的查看,函数中可以把图片顺便保存一下,总体看一下效果

1 from PIL importImage2

3 defpixel_wanted(pix):4 return pix==(237,28, 36)5

6 deffillPoly(im):7 coordinate_List =[]8

9 top_Pixel =(0,0,0)10 for x inrange(im.size[0]):11 flag = False #初始化每一列翻转位为False

12 for y in range(im.size[1]):13 current_pixel =im.getpixel((x,y))14 last_pixel = im.getpixel((x,y-1)) if y>0 elsetop_Pixel15 #翻转判定

16 if pixel_wanted(current_pixel) and\17 notpixel_wanted(last_pixel):18 flag =True19 if flag and notpixel_wanted(current_pixel):20 flag =False21 if(flag):22 coordinate_List.append((x,y))23 coordinate_Min_Max_List =[]24 #找最小最大

25 for i inrange(im.size[0]):26 min=-1

27 max=-1

28 for coordinate incoordinate_List:29 if coordinate[0] ==i:30 min = coordinate[1]31 max = coordinate[1]32 break

33 for coordinate incoordinate_List:34 if coordinate[0] ==i:35 if coordinate[1]>max:36 max = coordinate[1]37 coordinate_Min_Max_List.append(min)38 coordinate_Min_Max_List.append(max)39 #上色

40 for x inrange(im.size[0]):41 for y in range(im.size[1]):42 min = coordinate_Min_Max_List[x*2]43 max = coordinate_Min_Max_List[x*2+1]44 if min

48 pass

49 returnim50

51 defCal_S(im):52 im_0 =im.rotate(0)53 im_90 = im.rotate(90, expand=True)54

55 im_0 =fillPoly(im_0)56 im_90 =fillPoly(im_90)57 im_90 = im_90.rotate(-90, expand=True)58

59 i=060 for x inrange(im.size[0]):61 for y in range(im.size[1]):62 if(im_0.getpixel((x,y))==(0,255,0) and

63 im_90.getpixel((x,y))==(0,255,0)):64 im.putpixel((x,y),(0,255,0))65 i+=1

66 return i/(im.size[0]*im.size[1])

python求不规则图形面积_python计算不规则图形面积算法相关推荐

  1. python求阶乘之和_python计算阶乘前n项和

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 知道公式后就很简单了,利用for循环,第几行i+1就等于几,当然python中是 ...

  2. python求概率密度函数_python 计算概率密度、累计分布、逆函数的例子

    计算概率分布的相关参数时,一般使用 scipy 包,常用的函数包括以下几个: pdf:连续随机分布的概率密度函数 pmf:离散随机分布的概率密度函数 cdf:累计分布函数 百分位函数(累计分布函数的逆 ...

  3. python怎么算阶乘_Python 计算阶乘的算法

    希望你的坚持是因为热爱,而不是不甘 by:缘分落地 阶乘在高中的数学排列组合曾经出现过,相信各位都不陌生.举个栗子: N!= N * (N-1) * (N-2)......1 带入数字形象的看一遍,我 ...

  4. python求梯形面积_Python:使用梯形法则快速计算平均值

    使用Python,我必须处理一些数据. 在大约一千万个时间点,我得到了大约50个函数的值.这些值以2D列表形式给出matrix,即matrix[i]是值列表 [t_i, value of f1 at ...

  5. python求交点坐标_Python求两个圆的交点坐标或三个圆的交点坐标方法

    计算两个圆的交点 代码如下: # -*- coding: utf-8 -*- import math import numpy as np def insec(p1,r1,p2,r2): x = p1 ...

  6. python怎么算阶乘_python计算阶乘

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 问题本身很简单,主要是通过这个小问题来演示python的一些用法,例如测试代码运 ...

  7. python方差的计算公式_python计算均值方差

    原博文 2014-06-07 14:13 − 用Python求均值与方差,可以自己写,也可以借助于numpy,不过到底哪个快一点呢? 我做了个实验,首先生成9百万个样本: ```python nlis ...

  8. python求众数程序_python求众数问题实例

    本文实例讲述了python求众数问题的方法,是一个比较典型的应用.分享给大家供大家参考.具体如下: 问题描述: 多重集中重数最大的元素称为众数...就是一个可以有重复元素的集合,在这个集合中重复的次数 ...

  9. python求数字平均值_python 求10个数的平均数实例

    python 求10个数的平均数实例 更新时间:2019年12月16日 18:00:02 作者:qq_20076527 今天小编就为大家分享一篇python 求10个数的平均数实例,具有很好的参考价值 ...

  10. python 求最大值实例_Python 求数组局部最大值的实例

    求数组局部最大值 给定一个无重复元素的数组A[0-N-1],求找到一个该数组的局部最大值.规定:在数组边界外的值无穷小.即:A[0]>A[-1],A[N-1] >A[N]. 显然,遍历一遍 ...

最新文章

  1. c++大作业迷宫游戏 规定时间内完成_开卷有益 | 小学生做作业磨蹭的7个原因及对策!太准了~不得不为孩子收藏!...
  2. csdn无人驾驶汽车_无人驾驶汽车100年历史
  3. [转载]我的PMP复习备考经验谈(下篇)——一本关于PMP备考的小指南
  4. html5只能django来写if吗,(4)Django学习——模板标签定义及语法:for循环,if判断,页面跳转,开启关闭自动转义,ur...
  5. 分析优秀的.NET 文档设计工具Vsdocman 7.1 软件保护技术
  6. SpringCloud实战(四)Sentinel自定义降级异常实战
  7. opencv源码解析之(5):CommandLineParser类的简单理解
  8. 总结之Unix的基础知识
  9. 《通信原理与应用》小结
  10. 华为鸿蒙系统支持什么手机_华为鸿蒙系统支持的手机型号_华为鸿蒙系统最新消息...
  11. java 笔触类_下列属于笔触类型的绘图工具有那些?
  12. ue4导入倾斜摄影_倾斜摄影如何和bim结合?倾斜摄影数据怎么导?我来告诉你!...
  13. TypeError错误解决方案
  14. [LUOGU] P3354 [IOI2005]Riv 河流
  15. Vue自定义组件npm上传私服,且从私服下载使用
  16. 生成网络论文阅读:DDPM(一):Denoising Diffusion Probabilistic Models论文概述
  17. 在python中、下列哪些说法是错误的-Python支持复数类型,以下哪个说法是错误的?...
  18. vue echarts 地图立体 并设置tooltip属性背景图片
  19. Unity在OpenGL模式下Shader编译报错
  20. linux unix 可视化界面,Linux/UNIX远程调用图形化界面的一种方法

热门文章

  1. 大学计算机试题深圳大学,深圳大学期末考试试卷参考答案.doc
  2. 2015年ps计算机试题,2015年计算机一级考试《PS》模拟试题及答案(一)(2)
  3. Error: The specified query does not exist\nResponse from attempted peer comms was an error
  4. 服务器搬迁没有搭建文档,云服务器搬迁
  5. 从五个维度来谈谈视觉设计师如何阐述设计风格
  6. 如何把pdf文件变小一点?
  7. 五菱“神车”再添一员,小型电动车迎来“均值回归”?
  8. hadoop进阶---hadoop性能优化(一)---hdfs空间不足的管理优化
  9. 【微积分3一元函数积分学】第三章第三节 反常积分
  10. 查看linux主机防火墙列表,linux防火墙状态查看的方法实例