一尘不染

如何裁剪轮廓的内部区域?

python

我正在处理视网膜眼底图像。图像由黑色背景上的圆形视网膜组成。使用OpenCV,我设法获得了围绕整个圆形视网膜的轮廓。我需要的是从黑色背景中裁剪出圆形视网膜。


阅读 243

收藏
2020-12-20

共1个答案

一尘不染

在您的问题中尚不清楚,您是要实际裁剪轮廓中定义的信息还是要屏蔽与所选轮廓无关的信息。我将探讨在两种情况下该怎么做。


掩盖信息

假设您cv2.findContours在图像上运行,您将收到一个列出图像中所有可用轮廓的结构。我还假设您知道用来包围所需对象的轮廓的
索引
。假设将其存储在中idx,首先用于将该轮廓cv2.drawContours
填充 版本绘制到空白图像上,然后使用该图像索引到图像中以提取出对象。该逻辑 掩盖 了所有不相关的信息,只保留了重要的信息-
在所选轮廓中定义了重要信息。假设您的图像是存储在中的灰度图像,则执行此操作的代码应类似于以下内容img

import numpy as np
import cv2
img = cv2.imread('...', 0) # Read in your image
# contours, _ = cv2.findContours(...) # Your call to find the contours using OpenCV 2.4.x
_, contours, _ = cv2.findContours(...) # Your call to find the contours
idx = ... # The index of the contour that surrounds your object
mask = np.zeros_like(img) # Create mask where white is what we want, black otherwise
cv2.drawContours(mask, contours, idx, 255, -1) # Draw filled contour in mask
out = np.zeros_like(img) # Extract out the object and place into output image
out[mask == 255] = img[mask == 255]

# Show the output image
cv2.imshow('Output', out)
cv2.waitKey(0)
cv2.destroyAllWindows()

如果你真的想种…

如果要 裁剪
图像,则需要定义轮廓定义的区域的最小跨度边界框。您可以找到边界框的左上角和右下角,然后使用索引来裁剪出所需的内容。该代码将与以前相同,但是将有一个附加的裁剪步骤:

import numpy as np
import cv2
img = cv2.imread('...', 0) # Read in your image
# contours, _ = cv2.findContours(...) # Your call to find the contours using OpenCV 2.4.x
_, contours, _ = cv2.findContours(...) # Your call to find the contours
idx = ... # The index of the contour that surrounds your object
mask = np.zeros_like(img) # Create mask where white is what we want, black otherwise
cv2.drawContours(mask, contours, idx, 255, -1) # Draw filled contour in mask
out = np.zeros_like(img) # Extract out the object and place into output image
out[mask == 255] = img[mask == 255]

# Now crop
(y, x) = np.where(mask == 255)
(topy, topx) = (np.min(y), np.min(x))
(bottomy, bottomx) = (np.max(y), np.max(x))
out = out[topy:bottomy+1, topx:bottomx+1]

# Show the output image
cv2.imshow('Output', out)
cv2.waitKey(0)
cv2.destroyAllWindows()

裁剪代码的工作原理是,当我们定义蒙版以提取轮廓所定义的区域时,我们还会找到定义轮廓左上角的最小水平和垂直坐标。同样,我们找到了定义轮廓左下角的最大水平和垂直坐标。然后,我们使用这些坐标的索引来裁剪实际需要的内容。请注意,这会对
蒙版 图像进行裁切,该图像将除去除最大轮廓中包含的信息以外的所有内容。

注意与OpenCV 3.x

应该注意的是,以上代码假定您使用的是OpenCV2.4.x。请注意,在OpenCV
3.x中,的定义cv2.findContours已更改。具体来说,输出是一个三元素元组输出,其中第一个图像是源图像,而其他两个参数与OpenCV
2.4.x中的相同。因此,只需更改cv2.findContours以上代码中的语句即可忽略第一个输出:

_, contours, _ = cv2.findContours(...) # Your call to find contours
2020-12-20