我想要实现一个简单的功能即提取一个医学图像的轮廓计算边缘周长(这个医学图像读取之后是一个3d的矩阵,我选取其中一层就是一个普通的二维矩阵了),但是我提取的边缘还包含内部的,有什么办法可以去掉这些内部的边缘吗?这是我的代码:
from skimage.segmentation import find_boundaries
import cv2
import matplotlib.pyplot as plt
from PIL import Image
nii_file_path = r'file' # 文件路径
img = nib.load(nii_file_path)
data = img.get_fdata()
middle_slice = data[:, data.shape[1] // 2,:]
middle_slice[middle_slice < 200] = 0
threshold_value = threshold_otsu(middle_slice)
binary_image = middle_slice > threshold_value
outer_edges = find_boundaries(binary_image, mode='inner')
这是我提取之后的图像:
cv2我试过了,不行,因为有的线条是连着的被认为是一个轮廓了。
我换了个思路发现这个问题其实很简单,我直接按行遍历矩阵,把每一行最左边和最右边的非0值保留,其它值全部置零就好了,就能保留最外侧轮廓了
试试这个呢,用cv2.findContours函数来寻找轮廓,然后使用cv2.drawContours函数来绘制最外层的轮廓。这个函数可以通过mode参数来控制提取的轮廓层级,例如cv2.RETR_EXTERNAL表示只提取最外层的轮廓。Python + Opencv2 实现轮廓提取,轮廓区域面积计算
或者用scipy.ndimage.morphology.binary_erosion函数来对二值图像进行腐蚀操作,然后用原图像减去腐蚀后的图像,得到最外层的边缘。【深度好文】Python图像处理之目标物体轮廓提取
【以下回答由 GPT 生成】
Markdown格式的答案如下:
首先,可以使用OpenCV的findContours
函数来找到图像中的轮廓。然后,可以根据轮廓的层次结构信息来判断哪些轮廓是内部轮廓,哪些是外部轮廓。最后,可以使用drawContours
函数来绘制只包含最外围轮廓的图像。
以下是解决该问题的步骤:
步骤1:导入所需库
import cv2
import numpy as np
步骤2:找到图像中的轮廓
# 将图像转换为灰度图
gray_image = cv2.cvtColor(binary_image.astype(np.uint8) * 255, cv2.COLOR_BGR2GRAY)
# 找到轮廓
contours, _ = cv2.findContours(gray_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
步骤3:筛选出最外围的轮廓
# 创建一个新的图像,用于绘制筛选后的轮廓
filtered_image = np.zeros_like(binary_image)
# 筛选轮廓
filtered_contours = []
for contour in contours:
# 判断轮廓的层次结构
parent_idx = hierarchy[0][contour_idx][3]
if parent_idx == -1:
# 没有父轮廓,说明是最外围的轮廓
filtered_contours.append(contour)
# 绘制轮廓到新图像上
cv2.drawContours(filtered_image, filtered_contours, -1, 255, thickness=1)
步骤4:显示结果
# 显示原图像和筛选后的图像
plt.subplot(1, 2, 1)
plt.imshow(binary_image, cmap='gray')
plt.title('Original Image')
plt.subplot(1, 2, 2)
plt.imshow(filtered_image, cmap='gray')
plt.title('Filtered Image')
plt.show()
这样,最外围的轮廓就会被绘制到新图像上,并且内部轮廓被滤除,只保留最外围的那一条线。
请注意,以上代码是基于已有代码的修改,可能需要根据实际情况进行调整和优化。另外,关于hierarchy
变量的获取可能需要根据具体情况进行修改,详细使用方法可以参考OpenCV的文档。
希望这些步骤和代码能够对你有所帮助。如果还有其他问题,请随时提问。