分割结果可视化:怎么把标签mask轮廓显示在原图上

训练完模型得到视盘视杯的分割结构之后,查看论文中的示例图,分割结果的显示为:
在这里插入图片描述
下面是可视化过程中遇到的一些问题

问题1: 怎么可视化npy文件

cv2.imshow("ima", ima) # 需要两个参数 记住图片名称不可少
cv2.waitKey() # 等待时间 不写就是手动 0就是1s后会自动关闭

注意!!!
失败的原因 cv2显示的时候 图像必须是(h,w,c) 通道数在最后 否则出现报错
转换维度ima = image.transpose(1, 2, 0)
这里显示出来的图像颜色也很奇怪
查阅资料发现:
如果希望使用np.load读取图片,且使用cv2.imshow来输出正常照片的话,可以在输出时把颜色通道的顺序从BGR调整为RGB就行了。
opencv的接口使用BGR,而matplotlib.pyplot 则是RGB模式,所以将通道数进行对换一下即可

import cv2
 
image=np.load(image1)
ima = image.transpose(1, 2, 0) # 转化为(h,w,c)
ima_re = ima[:,:,::-1] # 转换成正常的颜色通道
cv2.imshow("ima", ima_re) # 需要两个参数 记住图片名称不可少
cv2.waitKey() # 等待时间 不写就是手动 0就是1s后会自动关闭

![[Pasted image 20221115145419.png|200]]![[Pasted image 20221115150023.png|200]]

问题2: 怎么保存这个jpg文件
这个Image就很正常了 注意的是.astype(np.uint8) 有时候会出现很奇怪报错就是因为他

from PIL import Image
file_name = file.split(".")[0] + "_" + file.split(".")[1] + '.jpg'
save_full_path = os.path.join(save_path, file_name)
img = Image.fromarray(res.astype(np.uint8), 'RGB')
img.save(save_full_path)

问题3: 怎么把分割的结果mask的轮廓在原图上显示
找了半天csdn终于成功得到我的分割结果图

注意: 使用下列方法之前我的mask是只有0-1两个值
1.将mask转化为 黑色背景,白色是分割mask
使用 图像二值化函数cv2.threshold函数
图像的二值化,就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的只有黑和白的视觉效果(灰度值0:黑,灰度值255:白).
原因:在图像中除了目标物体和背景区域,还有噪声,这都会对于我们对图像的识别造成困扰,所以我们要通过图像二值化函数将多值的数字图像中直接提取出目标图像,也就是说设定一个阈值T,用T将图像的像素群一分为二。

cv2.thresholdcv2.threshold(src, thresh, maxval, type) → ret, thresh
在函数中:
src:表示原图
thresh:表示阈值
maxval:表示最大值
type:表示的是划分的时候使用的是什么算法,二值化的方法,常用值为0(cv2.THRESH_BINARY)
ps:大于阈值就是最大值,小于阈值就是0 这里的阈值 要我们自己选择(我的mask是0-1,所以取了0.5)

第一个ret(得到的阈值值(这里是0.0)),第二个就是阈值化后的图像thresh。

出现问题:程序怎么也没反应,好像在运行但是又像卡住了

#错误写法:
ret, thresh = cv2.threshold(mask_dic, 0.5, 255, 0)
#正确写法
ret, thresh = cv2.threshold(mask_dic.astype(np.uint8), 0.5, 255, 0)

2.获取二值化后的mask的轮廓

cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])
函数参数:
image:参数是寻找轮廓的图像;
mode:参数表示轮廓的检索模式,有四种(下方介绍的都是新的cv2接口):
cv2.RETR_EXTERNAL:表示只检测外轮廓
cv2.RETR_LIST:检测的轮廓不建立等级关系
cv2.RETR_CCOMP:建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。
cv2.RETR_TREE:建立一个等级树结构的轮廓。
method:轮廓的近似办法:
cv2.CHAIN_APPROX_NONE:存储所有的轮廓点,相邻的两个点的像素位置差不超过1

返回值:
cv2.findContours() 函数返回两个值,一个是轮廓本身,还有一个是每条轮廓对应的属性。
contour返回值:返回一个list,list中每个元素都是图像中的一个轮廓,用numpy中的ndarray表示。
hierarchy返回值:返回一个ndarray,其中的元素个数和轮廓个数相同。

contours, im = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  # 第一个参数是轮廓

3.在原图上画上刚刚找到的轮廓
cv2.drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None)
第一个参数是指明在哪幅图像上绘制轮廓;image为三通道才能显示轮廓
第二个参数是轮廓本身,在Python中是一个list;
第三个参数指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。后面的参数很简单。其中thickness表明轮廓线的宽度,如果是-1(cv2.FILLED),则为填充模式。

出现报错:
TypeError: Expected Ptrcv::UMat for argument ‘image’
原因是:
image的数据之间出了冲突,需要在某些地方调用.copy函数
把原图加上.copy即可 后续保存如上

如果是多个mask的只要类似重复的在画好了第一个mask轮廓图上继续画轮廓即可

ret, thresh = cv2.threshold(mask_dic.astype(np.uint8), 0.5, 255, 0)
contours, im = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  # 第一个参数是轮廓
res1=cv2.drawContours(ima.copy(), contours=contours, contourIdx=-1, color=(64,224, 208), thickness=1)

获得如下图像:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ZLInbao/article/details/127867774