首先是老师布置的作业,叫我们练习区域生长,种子可以手动选取,但最好自动找出来。于是乎我就像挑战一下,感觉网上例程很多的样子,比如:

本人搜了半天,网上虽然看似很多,但就其根本就只有这一个。于是就用了一下其中的找种子环节(函数)。

#初始种子选择
def originalSeed(gray, th):ret, thresh = cv2.cv2.threshold(gray, th, 255, cv2.THRESH_BINARY)#二值图,种子区域(不同划分可获得不同种子)kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))#3×3结构元thresh_copy = thresh.copy() #复制thresh_A到thresh_copythresh_B = np.zeros(gray.shape, np.uint8) #thresh_B大小与A相同,像素值为0seeds = [ ] #为了记录种子坐标#循环,直到thresh_copy中的像素值全部为0while thresh_copy.any():Xa_copy, Ya_copy = np.where(thresh_copy > 0) #thresh_A_copy中值为255的像素的坐标thresh_B[Xa_copy[0], Ya_copy[0]] = 255 #选取第一个点,并将thresh_B中对应像素值改为255#连通分量算法,先对thresh_B进行膨胀,再和thresh执行and操作(取交集)for i in range(200):dilation_B = cv2.dilate(thresh_B, kernel, iterations=1)thresh_B = cv2.bitwise_and(thresh, dilation_B)#取thresh_B值为255的像素坐标,并将thresh_copy中对应坐标像素值变为0Xb, Yb = np.where(thresh_B > 0)thresh_copy[Xb, Yb] = 0#循环,在thresh_B中只有一个像素点时停止while str(thresh_B.tolist()).count("255") > 1:thresh_B = cv2.erode(thresh_B,  kernel, iterations=1) #腐蚀操作X_seed, Y_seed = np.where(thresh_B > 0) #取处种子坐标if X_seed.size > 0 and Y_seed.size > 0:seeds.append((X_seed[0], Y_seed[0]))#将种子坐标写入seedsthresh_B[Xb, Yb] = 0 #将thresh_B像素值置零return seeds

我怀着敬重的心情cv了一下,运行,发现我的pycharm没动静了。这是为什么呢?然后我仔细观察了一下代码,看到了其中的:

while{for(200次){}whlie(xxx > 1){}
}

是这种结构。。。其中那个for中间是一次腐蚀操作和并集操作。对于这么多像素都要做一次,这运算量可想而知。但我大概是了解这串操作是什么意思。大概是像通过腐蚀操作将此时图像中的连通域变小,然后一次次地迭代,找出每一个连通域的种子。
那么有没有更加方便地操作呢?
本人学图像处理时间也不多,深度也不深,但我想选取种子肯定得与连通域有关。我们想尽量选择每个连通域中较为中间地点,而且每个连通域尽量只取一个点来进行区域生长最合适。多的话会重复生长,浪费时间。那么,个人认为主要确实得通过腐蚀或者用其他方法使连通域变小,直到小到一定程度,取其中的一个点,把此连通域删除。即一层一层腐蚀,删除连通域进行迭代。但本人想了半天不知道怎么做。。。判断函数+删除连通域函数就很难马上实现(作业马上就要交了)。所以在网上搜了一下,发现了有连通域的专属操作:

connectedComponentsWithStats(image[,labels[,stats[, centroids[, connectivity[, ltype]]]]])
#-> retval, labels, stats, centroids

真好!

返回值里有一个centroids------质心?这个函数就是对于每个连通域进行轮廓的提取操作,质心刚好能实现在中间取一个点的操作。这里有人会问:质心不一定在连通域中怎么办?emmmm确实是一个问题。大家有好的方法可以在评论区说一下。那我现在就先将就一下。于是我把质心提取出来,又由于种子的位置一定是int型的,所以做个转化。提取seed的代码如下:

#初始种子选择
def originalSeed(gray):ret, img1 = cv2.threshold(gray, 245, 255, cv2.THRESH_BINARY)  # 二值图,种子区域(不同划分可获得不同种子)retval, labels, stats, centroids = cv2.connectedComponentsWithStats(img1)#进行连通域操作,取其质点centroids = centroids.astype(int)#转化为整数# seed = []# for i  in range(img1.shape[0]):#     for j in range(img1.shape[1]):#         if(img1[i,j] == 255):#             seed.append([i,j])return centroids

然后再结合老师原来的例程就可以实现了,还要记得将threshold设置成5。所以全程序如下:

import cv2
import numpy as np
import matplotlib.pyplot as plt#求两个点的差值
def getGrayDiff(image,currentPoint,tmpPoint):return abs(int(image[currentPoint[0],currentPoint[1]]) - int(image[tmpPoint[0],tmpPoint[1]]))
#区域生长算法
def regional_growth (gray,seeds,threshold=5) :#每次区域生长的时候的像素之间的八个邻接点connects = [(-1, -1), (0, -1), (1, -1), (1, 0), (1, 1), \(0, 1), (-1, 1), (-1, 0)]threshold = threshold #生长时候的相似性阈值,默认即灰度级不相差超过15以内的都算为相同height, weight = gray.shapeseedMark = np.zeros(gray.shape)seedList = []for seed in seeds:if(seed[0] < gray.shape[0] and seed[1] < gray.shape[1] and seed[0]  > 0 and seed[1] > 0):seedList.append(seed)   #将添加到的列表中print(seedList)label = 1   #标记点的flagwhile(len(seedList)>0):     #如果列表里还存在点currentPoint = seedList.pop(0)  #将最前面的那个抛出seedMark[currentPoint[0],currentPoint[1]] = label   #将对应位置的点标志为1for i in range(8):  #对这个点周围的8个点一次进行相似性判断tmpX = currentPoint[0] + connects[i][0]tmpY = currentPoint[1] + connects[i][1]if tmpX < 0 or tmpY < 0 or tmpX >= height or tmpY >= weight:    #如果超出限定的阈值范围continue    #跳过并继续grayDiff = getGrayDiff(gray,currentPoint,(tmpX,tmpY))   #计算此点与像素点的灰度级之差if grayDiff < threshold and seedMark[tmpX,tmpY] == 0:seedMark[tmpX,tmpY] = labelseedList.append((tmpX,tmpY))return seedMark#初始种子选择
def originalSeed(gray):ret, img1 = cv2.threshold(gray, 245, 255, cv2.THRESH_BINARY)  # 二值图,种子区域(不同划分可获得不同种子)retval, labels, stats, centroids = cv2.connectedComponentsWithStats(img1)#进行连通域操作,取其质点centroids = centroids.astype(int)#转化为整数# seed = []# for i  in range(img1.shape[0]):#     for j in range(img1.shape[1]):#         if(img1[i,j] == 255):#             seed.append([i,j])return centroids# if __name__ == "__main__":
img = cv2.imread('10.2.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
seed = originalSeed(img)
img = regional_growth(img,seed)# 用来正常显示中文标签
plt.rcParams['font.sans-serif'] = ['SimHei']
# 图像显示
plt.figure(figsize=(10, 5))  # width * height
plt.subplot(111), plt.imshow(img, cmap='gray'), plt.title('区域生长以后'), plt.axis("off")
plt.show()
print("ok...")

效果如下:

右边虽然有点噪声,但可以通过滤波器消去。
然后如果你老师也是付老师的话,那就点个赞或者评论一下吧!哈哈哈!

opencv 区域生长(种子自动选取)python相关推荐

  1. 【机器视觉学习笔记】python安装OpenCV并设置自动补全及代码提示

    目录 安装 测试 设置自动补全及代码提示 平台:Windows 10 20H2 Python 3.8.12 (default, Oct 12 2021, 03:01:40) [MSC v.1916 6 ...

  2. python opencv vscode 增加自动补全 auto completement

    python opencv vscode 增加自动补全 auto completement 现状 解决方法 参考 现状 vscode中使用opencv时,无法自动补全. 解决方法 自己生成 pyi 文 ...

  3. python自动选取空闲gpu

    自动选取可用gpu pip install nvidia-ml-py==4.304.04 pip安装pynvml pip install nvidia-ml-py3 如果是Python2,则pip n ...

  4. python打卡以及Linux自动运行python文件

    python打卡以及Linux自动运行python文件 前因 分析 python代码 实现linux自动运行python文件 了解crond 开机自启设置 定时运行python文件设置 crond踩坑 ...

  5. python扫雷_自动扫雷 Python语言

    本文主要向大家介绍了自动扫雷 Python语言,通过具体的内容向大家展示,希望对大家学习Python语言有所帮助. 自动扫雷一般分为两种,一种是读取内存数据,而另一种是通过分析图片获得数据,并通过模拟 ...

  6. python运维脚本部署jdk_Jenkins自动执行Python脚本,并输出测试报告

    这段时间,在家时间自由(除了睡觉8小时,其他时间都在工作和学习),有大把的时间实操练习一些硬技能: 今天,更新一篇利用Jenkins这套框架,调用Python自动化脚本,并输出测试报告的手把手实操文章 ...

  7. pycharm打开python文件如何自动创建项目_pycharm 怎么自动创建python头文件?

    展开全部 创建方法如下: 进入File->settings->Editor->File and Code Templates->Python Script. 添加以下内容: 1 ...

  8. python 任务计划_windows 10 设定计划任务自动执行 python 脚本的方法

    我用 python 写了一些脚本,有一些是爬虫脚本,比如爬取知乎特定话题的热门问题,有一些是定期的统计分析脚本,输出统计结果到文档中.之前我都是手动执行这些脚本,现在我希望如何这些脚本能自动定时执行. ...

  9. jenkins 手动执行_想知道如何用Jenkins自动执行Python脚本输出测试报告?

    前言在用python做自动化测试时,我们写好代码,然后需要执行才能得到测试报告,这时我们可以通过 Jenkins 来进一步完成自动化工作.借助Jenkins,我们可以结合 Git/SVN 自动拉取代码 ...

最新文章

  1. 马斯克炮轰元宇宙与Web3.0:“我不觉得有人会成天把屏幕绑在脑袋上”
  2. 以营销型网站为例,网站建设过程中需要注意哪些问题?
  3. 完整的一次 HTTP 请求响应过程(一)
  4. 关于Oracle Insert 语句的子查询 和 with check option的用法
  5. Ember.js 入门指南——路由切换的终止和回跳
  6. UVA - 514 Rails-栈
  7. link url下载php,php脚本生成google play url的下载链接,下载apk并自动反编译后获取android版本号...
  8. 阶级斗争的作用_21世纪的阶级斗争
  9. java对csv格式的读写操作
  10. tornado web mysql_Tornado WEB服务器框架 Epoll-- 【Mysql数据库】
  11. jmeter压力性能测试-多台机器并发请求
  12. kubernetes集群pod异常状态ContainerCreating的解决
  13. WAP网站源代码--WAP新闻(文章)系统调试实战
  14. Python实现快速查找文件
  15. mysql内连接去重复_MYSQL 内连接查询重复
  16. 翠竹林 Opencv+C++之人脸识别
  17. git本地无法上传到远程的问题解决方法
  18. 假设从键盘输入从某日凌晨零点零分零秒到现在已经经历的时间(单位:秒),编译程序计算到现在为止已经过了多少天?现在的时间是多少?
  19. BZOJ 4833: [Lydsy1704月赛]最小公倍佩尔数(数论 + 最值反演)
  20. 那些辉煌的背后, 不知装载了多少苦涩

热门文章

  1. 链表排序时间复杂度为(O(n log n) )
  2. 极致视觉追求 六款热门高清屏笔记本推荐
  3. XCode下Object C和C++混合编译
  4. Mysql之高可用方案浅析
  5. [转]一个男朋友写给女朋友的信
  6. AWS CLI创建Amazon EKS服务
  7. 销毁session的四种方法
  8. Android Studio (version 4.1) Flutter plugin not installed; this adds Flutter specific function
  9. Windows6.1-KB2731771-x64.msu 提示此更新不适用于您的计算机 ie10 ie11 安装失败
  10. 小程序毕设作品之微信校园浴室预约小程序毕业设计成品(6)开题答辩PPT