一.概念

1.简述Radon变换检测直线的原理。

Radon变换就是将数字图像矩阵在某一角度射线方向上做投影变换,按照投影方向累加像素。

2.简述基于区域生长的图像分割的原理。

根据同一物体区域内像素相似性质来聚集像素点。选定图像中的一个点(或一组点),从初始起点开始,将相邻的具有同样性质的像素或归并到目前的区域中从而逐步增长区域,直到没有可以归并的点为止。

3. 简述基于分水岭算法进行图像分割的原理。

将图像看作拓扑地貌,图像中的每一点像素的灰度值表示该点的海拔高度,每一局部极小值及其影响区域就是集水盆地,集水盆地的边界则形成分水岭。在每一个局部最小值表面刺穿一个孔,然后向模型里注水,随着水量增多,局部最小值的影响逐渐向外扩展,而集水盆间交界处筑成大坝即形成分水岭。

4.如何计算一个区域内部的一致性或者平滑性

方法一:Sobel算子利用像素邻近区域的梯度值来计算一个像素的梯度,再根据一定的绝对值来判断其是不是噪声点。

方法二:计算图像一块区域的像素平均值,再算出该区域内每个点像素值与均值的差绝对值,设定阈值,大于某个阈值则该点算为噪声点。

5.如何计算两个区域之间的相似性或者距离

方法一:Kolmogorov-Smirnov检验:统计两个区域0-255每个像素值出现的次数,比较像数值的频率分布,两个区域间每个元素对应一个频率差值,如果最大的频率差值小于规定的值,则两区域相似,反之不相似。

方法二:通过直方图余弦值计算相似性。将两区域像素点的灰度值统计成直方图,压缩灰度级别,每间隔四个数合为一个分向量,共分为64个分向量,记作一个向量;计算2个区域向量夹角的余弦值,作为相似度。

二.编程题

1.图像分割的目的是把图像分割成若干区域。请查阅相关文档,理解如何计算分割算法准确率。写出函数实现该方法。

1.1平均交并比原理:

1.2 函数实现:

def create_hist(a,b,n):""":param a: 形状为H*W的预测值(H为高,W为宽):param b: 形状为H*W的真实值(H为高,W为宽):param n: 类别数:return: 混淆矩阵"""#确保a和b在0~n-1的范围内k = (a>=0)&(a<n)return np.bincount(n*a[k].astype(int) + b[k],minlength=n**2).reshape(n,n)def per_iou(hist):""":param hist:传入混淆矩阵(n,n):return: 每个类别的iou"""#因为交并比有除法,防止分母出现0报错np.seterr(divide="ignore",invalid="ignore")#交集:np.diag取对角线元素#并集:hist.sum(0)和hist.sum(1)两个维度相加,减去多加了一次的对角线元素iou = np.diag(hist) / (hist.sum(0)+hist.sum(1)-np.diag(hist))#把报错调回来np.seterr(divide="warn",invalid="warn")#分母为0时结果是Nan,将Nan值改为0iou[np.isnan(iou)] = 0return iou

2 .针对shapes.png, 利用颜色信息把图像进行分割,把结果作为分割的标准答案。

2.1流程

2.2代码:

#生成初始种子
def originaSeed(gray):""":param gray: 传入灰度图:return:  连通域中心"""ret,img1 = cv2.threshold(gray,245,255,cv2.THRESH_BINARY)#二值化num_labels,labels,stats,centroids = cv2.connectedComponentsWithStats(img1)#进行连通域连通centroids = centroids.astype(int)return centroids#求两个点像素值差值
def Graydiff(gray,currentpoint,tmppoint):return abs(int(gray[currentpoint[0],currentpoint[1]])-int(gray[tmppoint[0],tmppoint[1]]))#区域生长
def regional_growth(gray,seeds):""":param gray:灰度图片:param seeds:初始种子,连通域中心:return:图片矩阵"""#像素种子的8个邻接点approximal_point = [(-1,-1),(0, -1), (1, -1), (1, 0),(1, 1), (0, 1), (-1, 1), (-1, 0)]threshold = 5 #生长相似性的阈值,Graydiff不超过5就符合height,weight = gray.shapeimg = np.zeros(gray.shape)#创建等灰度图尺寸的矩阵,满足生长规则的点改为1seedlist = []for seed in seeds:#种子位置大于0且不超过图片尺寸if (seed[0] < gray.shape[0] and seed[1] < gray.shape[1] and seed[0] > 0 and seed[1] > 0):seedlist.append(seed)while len(seedlist)>0:#循环到列表中没有种子点currentPoint = seedlist.pop(0)#最新的种子点等于列表里的第一个种子点,同时取出第一个点后删除该点做到列表更新img[currentPoint[0],currentPoint[1]] = 1#找到对应位置把0改为1#对该位置8领域进行象素差判断for i in range(8):tmpX = currentPoint[0] + approximal_point[i][0]tmpY = currentPoint[1] + approximal_point[i][1]if tmpX < 0 or tmpY <0 or tmpX >= height or tmpY >= weight:#如果位置值超过图片大小或者非正数continue#跳过并继续grayDiff = Graydiff(gray,currentPoint,(tmpX,tmpY))#计算像素差if grayDiff < threshold and img[tmpX,tmpY]==0:#如果小于阈值并且矩阵该点为0img[tmpX,tmpY] = 1seedlist.append((tmpX,tmpY))return imgdef original_growth():img = cv2.imread('E:\\Machine vision\\images\\images\\shapes.png')img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)o_img = copy.deepcopy(img)seed = originaSeed(img)img = regional_growth(img,seed)#显示区域生长效果plt.rcParams['font.sans-serif'] = ['SimHei']#正常显示中文标签plt.figure(figsize=(10, 5))plt.subplot(121), plt.imshow(o_img, cmap='gray'), plt.title('区域生长前'),plt.axis("off")plt.subplot(122),plt.imshow(img,cmap='gray'),plt.title('区域生长以后'),plt.axis("off")plt.show()
test_original_growth()

2.3原图及效果展示(左原右结果)

3.针对shapes.png, 利用opencv的K-Means方法对图像进行分割,基于2.1和2.2计算分割准确率,并展示效果图。

3.1代码

def kmeans_segmentation():image = cv2.imread('E:\\Machine vision\\images\\images\\shapes.png')image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)#展成一维img1 = image.reshape((image.shape[0] * image.shape[1], 1))img1 = np.float32(img1)#迭代终止条件:精度满足0.2/迭代次数超过阈值100criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.2)k = 3# cv2.kmeans返回紧密度、标签、聚类中心compactness, labels, (centers) = cv2.kmeans(img1, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)#每次随机选择中心# 标签尺寸改变为原图尺寸img2 = labels.reshape((image.shape[0], image.shape[1]))plt.figure()plt.imshow(img2),plt.title('segmented image'),plt.axis('off')plt.show()return img2def iou_test():true_img = np.int64(original_growth())predict_img = np.int64(kmeans_segmentation())hist = create_hist(predict_img,true_img,3)#获取混淆矩阵iou = per_iou(hist)#获取每一类的ioum_iou = np.sum(iou)result = m_iou/3#求预测的平均值return result
print("准确率为{}".format(iou_test()))

3.2效果图

4.实现基于区域分裂合并的分割方法。请自行定义区域分裂和合并的准则,并在shapes.png 进行测试,计算出准确率,展示效果图。

4.1算法思想:

4.2代码

#判断区域是否需要再拆分为四个
def judge(img,x0,y0,w,h):arr = img[y0:y0+h,x0:x0+w]ave = np.mean(arr)#求平均std = np.std(arr)#计算标准差count = len(np.where(img - ave < std)[1])#判断区域相似度acc = w * hif count/acc<0.95:#判断该区域是否还需要再分return Falseelse:return Truedef recursion(img,x0,y0,w,h):#递归if judge(img,x0,y0,w,h) and (min(w,h)>5):#不用细分到每个像素点为一个区域recursion(img,x0,y0,int(w/2),int(h/2))recursion(img,x0+int(w/2),y0,int(w/2),int(h/2))recursion(img,x0,y0+int(h/2),int(w/2),int(h/2))recursion(img,x0+int(w/2),y0+int(h/2),int(w/2),int(h/2))else:ret,img = cv2.threshold(img,125,255,cv2.THRESH_BINARY)return imgdef rec_test():img = cv2.imread('E:\\Machine vision\\images\\images\\shapes.png')gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#灰度转换cv2.imshow('input',gray)cv2.waitKey(0)height, width = gray.shapeout_img = recursion(gray,0,0,width,height)cv2.imshow('output',out_img)cv2.waitKey(0)

5.写出代码,综合运用图像处理和分割的有关算法,在oranges.png中检测橘子,展示检测效果图

5.1过程

5.2代码

def oranges():img = cv2.imread('E:\\Machine vision\\images\\images\\oranges.png')  # 读取图片gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 灰度图转化ret, thresh = cv2.threshold(gray, 0, 255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)  # 图像二值化,cv2.THRESH_BINARY+cv2.THRESH_OTSU作用是自适应阈值kernel = np.ones((5, 5), np.uint8)opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)  # 开操作:去除噪声sure_bg = cv2.dilate(opening, kernel, iterations=3)  # 腐蚀操作,减小前景物体dist_transform = cv2.distanceTransform(sure_bg, cv2.DIST_L2, 5)  # 距离变换:得到每个非零像素点与其最近的零像素点之间的距离,输出为距离ret, sure_fg = cv2.threshold(dist_transform, 0.53 * dist_transform.max(), 255,0)  # 二值化操作,阈值为距离变换得到的距离,分离前景中的粘连物体sure_fg = np.uint8(sure_fg)  # 转化数据类型,连通域函数接收8位单通道二值图像# 连通域函数:label与原图大小一致,对应为当前像素为第几个轮廓;stats对应轮廓信息,每行有五个值,分别为x,y,width,height,area;centroids对应每个连通区域的质心点retval, labels, stats, centroids = cv2.connectedComponentsWithStats(sure_fg)for i in range(1, len(centroids)):cv2.circle(img, (int(centroids[i, 0]), int(centroids[i, 1])), 6, [255, 0, 0], -1)  # 勾画质心点,实心圆cv2.putText(img, str(i), (int(centroids[i, 0]), int(centroids[i, 1])), cv2.FONT_HERSHEY_SIMPLEX, 0.5,(0, 255, 0))  # 标记对应质心点的编号,最大值为个数-1print('计数个数:', len(centroids) - 1)cv2.imshow('img',img)cv2.waitKey(0)
oranges()

5.3原图及效果展示

基于python中cv2库的图像分割相关推荐

  1. python中cv2库_Python cv2库(人脸检测)

    根据访问图片识别 # coding:utf-8 import sys import math import cv2 # 待检测的图片路径 imagepath = r'l.png' face_casca ...

  2. 基于python中selenium库,实现百度账号的自动登陆

    1.如何实现自动打开百度网页并登录账号 首先使用chrome浏览器自动打开百度页面,然后寻找到登陆按键的节点元素,并实现点击.接着,找到用户名登陆的节点元素,实现扫码登陆到用户名登陆的切换.然后,找到 ...

  3. CV:计算机视觉技术之图像基础知识(一)—以python的cv2库来了解计算机视觉图像基础(傅里叶变换-频域-时域/各种滤波器-线性-非线性-均值-中值-高斯-双边)

    CV:计算机视觉技术之图像基础知识(一)-以python的cv2库来了解计算机视觉图像基础(傅里叶变换-频域-时域/各种滤波器-线性-非线性-均值-中值-高斯-双边) 目录 一.图像中的傅里叶变换 1 ...

  4. python人脸识别库_基于Python的face_recognition库实现人脸识别

    Python Python开发 Python语言 基于Python的face_recognition库实现人脸识别 一.face_recognition库简介 face_recognition是Pyt ...

  5. python opencv创建图像_使用Python中OpenCV库创建一幅图片的RGB通道图片

    我们知道,在使用PhotoShop进行图片的抠取.创建和存储选区.存储图像的色彩资料等复杂操作时,经常会用到一个功能,那就是"RGB"通道,它能从三原色角度对一幅图片进行精准处理. ...

  6. python中requests库的用途-数据爬虫(三):python中requests库使用方法详解

    有些网站访问时必须带有浏览器等信息,如果不传入headers就会报错,如下 使用 Requests 模块,上传文件也是如此简单的,文件的类型会自动进行处理: 因为12306有一个错误证书,我们那它的网 ...

  7. CV:计算机视觉技术之图像基础知识—以python的cv2库来了解计算机视觉图像基础

    CV:计算机视觉技术之图像基础知识-以python的cv2库来了解计算机视觉图像基础 目录 一.图像中的傅里叶变换 1.时域和频域 2.傅里叶变换 3.图像中的傅里叶变换

  8. python 颜色_如何使用python中matplotlib库分析图像颜色

    用代码分析图像可能很困难.你如何使代码"理解"图像的上下文? 通常,使用AI分析图像的第一步 是找到主要颜色.在如何使用python中matplotlib库分析图像颜色中,我们将使 ...

  9. python os模块安装方法_基于python中pygame模块的Linux下安装过程(详解)

    一.使用pip安装Python包 大多数较新的Python版本都自带pip,因此首先可检查系统是否已经安装了pip.在Python3中,pip有时被称为pip3. 1.在Linux和OS X系统中检查 ...

最新文章

  1. Vue插槽 slot
  2. 用机器学习神器sklearn做特征工程!
  3. Win Ser 2008/2012 (R2) + NVIDIA Optimus 笔记本显卡
  4. bootstrap mysql分页_bootstrap分页
  5. 浮点数能够表示的数的范围是由其()的位数决定的。
  6. 用Windows组件库文件快速部署Visual C
  7. kali linux解密栅栏密码,最详细bugku加密小白解法---持续更新!
  8. WIN10 vagrant和virtualbox虚拟机和一键搭建lnmp环境配置thinkphp虚拟主机
  9. (二十)java版spring cloud+spring boot 社交电子商务平台-spring cloud构建全球多租户分布式微服务部署的方案...
  10. xgboost算法_XGBoost 原理 及 常见面试题
  11. Android 文件md5校验
  12. INVEST模型生境质量评价之威胁源数据处理
  13. MoviePy问题解决汇总
  14. python绘制网格线在原图上面_在pyqtgraph中在图像上显示网格线
  15. 阿里云ECS服务器跨账号迁移
  16. 用尽可能多的字数介绍Leaky ReLU激活函数
  17. RTU、FTU、DTU、TTU都是什么鬼?
  18. 显示类型转换和隐式类型转换
  19. 硬核解析Promise对象(这七个必会的常用API和七个关键问题你都了解吗?)
  20. iPhone在中国大幅降价说明确实不好卖了

热门文章

  1. Solidworks 无法显示略缩图解决办法
  2. 枚举算法实践3-Lucky number c++
  3. FreeBSD常用命令
  4. VSCode中i18n ally插件无效的几个原因
  5. Asp.Net初学小结
  6. MATLAB一直显示初始化的解决方法
  7. 微信小程序如何批量生成带参数的小程序码,无需开发
  8. 【Python Matplotlib】设置横纵单位长度相同
  9. python os.path.split_python 中的split()函数和os.path.split()函数
  10. 自考计算机数据结构导论,自考数据结构导论……