Python计算不规则图形面积算法实现解析


Posted in Python onNovember 22, 2019

这篇文章主要介绍了Python计算不规则图形面积算法实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

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

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

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

Python计算不规则图形面积算法实现解析

算法实现

全程只用pillow库

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

def pixel_wanted(pix):
   return pix==(237,28, 36)

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

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

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

coordinate_List = []
top_Pixel = (0,0,0)
for x in range(im.size[0]):
  flag = False #初始化每一列翻转位为False
  for y in range(im.size[1]):
    current_pixel = im.getpixel((x,y))
    last_pixel = im.getpixel((x,y-1)) if y>0 else top_Pixel
    #翻转判定
    if pixel_wanted(current_pixel) and \
        not pixel_wanted(last_pixel):
      flag = True
    if flag and not pixel_wanted(current_pixel):
      flag = False
    if(flag):
      coordinate_List.append((x,y))

coordinate_List中的点如下图

Python计算不规则图形面积算法实现解析

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

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

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

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

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

coordinate_Min_Max_List = []
#找最小最大
for i in range(im.size[0]):
  min=-1
  max=-1
  for coordinate in coordinate_List:
    if coordinate[0] == i:
      min = coordinate[1]
      max = coordinate[1]
      break
  for coordinate in coordinate_List:
    if coordinate[0] == i:
      if coordinate[1]>max:
        max = coordinate[1]
  coordinate_Min_Max_List.append(min)
  coordinate_Min_Max_List.append(max)

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

Python计算不规则图形面积算法实现解析Python计算不规则图形面积算法实现解析

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

Python计算不规则图形面积算法实现解析

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

#上色
for x in range(im.size[0]):
  for y in range(im.size[1]):
    min = coordinate_Min_Max_List[x*2]
    max = coordinate_Min_Max_List[x*2+1]
    if min<y<max:
      im.putpixel((x,y),(0,255,0))
    else:
      #可以把非红圈的上掩膜遮住
      pass

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

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

def Cal_S(im):
  im_0 = im.rotate(0)
  im_90 = im.rotate(90, expand=True)
  
  im_0 = fillPoly(im_0)
  im_90 = fillPoly(im_90)
  im_90 = im_90.rotate(-90, expand=True)

  i=0
  for x in range(im.size[0]):
    for y in range(im.size[1]):
      if(im_0.getpixel((x,y))==(0,255,0) and
      im_90.getpixel((x,y))==(0,255,0)):
        im.putpixel((x,y),(0,255,0))
        i+=1
  return i/(im.size[0]*im.size[1])

做两遍的效果图

Python计算不规则图形面积算法实现解析Python计算不规则图形面积算法实现解析

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

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

Python计算不规则图形面积算法实现解析

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

from PIL import Image

def pixel_wanted(pix):
  return pix==(237,28, 36)

def fillPoly(im):
  coordinate_List = []

  top_Pixel = (0,0,0)
  for x in range(im.size[0]):
    flag = False #初始化每一列翻转位为False
    for y in range(im.size[1]):
      current_pixel = im.getpixel((x,y))
      last_pixel = im.getpixel((x,y-1)) if y>0 else top_Pixel
      #翻转判定
      if pixel_wanted(current_pixel) and \
          not pixel_wanted(last_pixel):
        flag = True
      if flag and not pixel_wanted(current_pixel):
        flag = False
      if(flag):
        coordinate_List.append((x,y))
  coordinate_Min_Max_List = []
  #找最小最大
  for i in range(im.size[0]):
    min=-1
    max=-1
    for coordinate in coordinate_List:
      if coordinate[0] == i:
        min = coordinate[1]
        max = coordinate[1]
        break
    for coordinate in coordinate_List:
      if coordinate[0] == i:
        if coordinate[1]>max:
          max = coordinate[1]
    coordinate_Min_Max_List.append(min)
    coordinate_Min_Max_List.append(max)
  #上色
  for x in range(im.size[0]):
    for y in range(im.size[1]):
      min = coordinate_Min_Max_List[x*2]
      max = coordinate_Min_Max_List[x*2+1]
      if min<y<max:
        im.putpixel((x,y),(0,255,0))
      else:
        #可以把非红圈的上掩膜遮住
        pass
  return im

def Cal_S(im):
  im_0 = im.rotate(0)
  im_90 = im.rotate(90, expand=True)

  im_0 = fillPoly(im_0)
  im_90 = fillPoly(im_90)
  im_90 = im_90.rotate(-90, expand=True)

  i=0
  for x in range(im.size[0]):
    for y in range(im.size[1]):
      if(im_0.getpixel((x,y))==(0,255,0) and
      im_90.getpixel((x,y))==(0,255,0)):
        im.putpixel((x,y),(0,255,0))
        i+=1
  return i/(im.size[0]*im.size[1])

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python Trie树实现字典排序
Mar 28 Python
Linux下Python获取IP地址的代码
Nov 30 Python
Python中zfill()方法的使用教程
May 20 Python
python定时器(Timer)用法简单实例
Jun 04 Python
Python使用PIL库实现验证码图片的方法
Mar 11 Python
Python基于回溯法解决01背包问题实例
Dec 06 Python
python中实现控制小数点位数的方法
Jan 24 Python
python利用多种方式来统计词频(单词个数)
May 27 Python
python将excel转换为csv的代码方法总结
Jul 03 Python
python opencv将图片转为灰度图的方法示例
Jul 31 Python
Python 用turtle实现用正方形画圆的例子
Nov 21 Python
解决pycharm中opencv-python导入cv2后无法自动补全的问题(不用作任何文件上的修改)
Mar 05 Python
python实现连续变量最优分箱详解--CART算法
Nov 22 #Python
pycharm运行scrapy过程图解
Nov 22 #Python
python迭代器常见用法实例分析
Nov 22 #Python
python自动分箱,计算woe,iv的实例代码
Nov 22 #Python
python创建学生管理系统
Nov 22 #Python
Python如何计算语句执行时间
Nov 22 #Python
python生成器用法实例详解
Nov 22 #Python
You might like
PHP设计模式之命令模式的深入解析
2013/06/13 PHP
PHP简单判断字符串是否包含另一个字符串的方法
2016/03/25 PHP
javaScript arguments 对象使用介绍
2013/10/18 Javascript
jquery的clone方法应用于textarea和select的bug修复
2014/06/26 Javascript
javascript中sort()的用法实例分析
2015/01/30 Javascript
jquery实现表格本地排序的方法
2015/03/11 Javascript
JavaScript实现将xml转换成html table表格的方法
2015/04/17 Javascript
AngularJS动态生成div的ID源码解析
2016/08/29 Javascript
常用Javascript函数与原型功能收藏(必看篇)
2016/10/09 Javascript
AngularJS框架中的双向数据绑定机制详解【减少需要重复的开发代码量】
2017/01/19 Javascript
使用原生的javascript来实现轮播图
2017/02/24 Javascript
vue中将网页打印成pdf实例代码
2017/06/15 Javascript
jQuery动态添加.active 实现导航效果代码思路详解
2017/08/29 jQuery
vue 做移动端微信公众号采坑经验记录
2018/04/26 Javascript
JavaScript的词法结构精华篇
2018/10/17 Javascript
vue动态配置模板 'component is'代码
2019/07/04 Javascript
在Vue中实现随hash改变响应菜单高亮
2020/03/09 Javascript
JavaScript 中判断变量是否为数字的示例代码
2020/10/22 Javascript
[07:20]2018DOTA2国际邀请赛寻真——逐梦Mineski
2018/08/10 DOTA
[42:52]Optic vs Serenity 2018国际邀请赛淘汰赛BO3 第二场 8.22
2018/08/23 DOTA
[40:31]Secret vs Alliacne 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Python的多维空数组赋值方法
2018/04/13 Python
对numpy中array和asarray的区别详解
2018/04/17 Python
Python简易版图书管理系统
2019/08/12 Python
python爬虫实现获取下一页代码
2020/03/13 Python
Python爬取YY评级分数并保存数据实现过程解析
2020/06/01 Python
CSS3媒体查询Media Queries基础学习教程
2016/02/29 HTML / CSS
以设计师精品品质提供快速时尚:Mostata
2019/05/10 全球购物
土耳其风格手工珠宝:Ottoman Hands
2019/07/26 全球购物
哈萨克斯坦移动和数字技术在线商店:SatelOnline.kz
2020/09/04 全球购物
有针对性的求职自荐信
2013/11/14 职场文书
实用的简历自我评价
2014/03/06 职场文书
财务部副经理岗位职责
2014/03/14 职场文书
小学语文教研活动总结
2014/07/01 职场文书
警察群众路线整改措施
2014/09/26 职场文书
解放思想大讨论活动总结
2015/05/09 职场文书