如何裁剪轮廓的内部区域? [英] How to crop the internal area of a contour?

查看:748
本文介绍了如何裁剪轮廓的内部区域?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究视网膜眼底图像。图像由黑色背景上的圆形视网膜组成。通过OpenCV,我设法获得了围绕整个圆形Retina的轮廓。我需要的是从黑色背景中裁剪掉圆形视网膜。

I am working on Retinal fundus images.The image consists of a circular retina on a black background. With OpenCV, I have managed to get a contour which surrounds the whole circular Retina. What I need is to crop out the circular retina from the black background.

推荐答案

你的问题中是否还不清楚你是否想要实际上裁剪出轮廓中定义的信息或掩盖与所选轮廓无关的信息。我将探讨在两种情况下该怎么做。

It is unclear in your question whether you want to actually crop out the information that is defined within the contour or mask out the information that isn't relevant to the contour chosen. I'll explore what to do in both situations.

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

Assuming you ran cv2.findContours on your image, you will have received a structure that lists all of the contours available in your image. I'm also assuming that you know the index of the contour that was used to surround the object you want. Assuming this is stored in idx, first use cv2.drawContours to draw a filled version of this contour onto a blank image, then use this image to index into your image to extract out the object. This logic masks out any irrelevant information and only retain what is important - which is defined within the contour you have selected. The code to do this would look something like the following, assuming your image is a grayscale image stored in img:

import numpy as np
import cv2
img = cv2.imread('...', 0) # Read in your image
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()



如果你真的想裁剪...



如果你想裁剪图像,你需要定义最小的跨越边界框由轮廓定义的区域。您可以找到边界框的左上角和右下角,然后使用索引来裁剪出您需要的内容。代码将与之前相同,但会有一个额外的裁剪步骤:

If you actually want to crop...

If you want to crop the image, you need to define the minimum spanning bounding box of the area defined by the contour. You can find the top left and lower right corner of the bounding box, then use indexing to crop out what you need. The code will be the same as before, but there will be an additional cropping step:

import numpy as np
import cv2
img = cv2.imread('...', 0) # Read in your image
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
(x, y) = np.where(mask == 255)
(topx, topy) = (np.min(x), np.min(y))
(bottomx, bottomy) = (np.max(x), np.max(y))
out = out[topx:bottomx+1, topy:bottomy+1]

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

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

The cropping code works such that when we define the mask to extract out the area defined by the contour, we additionally find the smallest horizontal and vertical coordinates which define the top left corner of the contour. We similarly find the largest horizontal and vertical coordinates that define the bottom left corner of the contour. We then use indexing with these coordinates to crop what we actually need. Note that this performs cropping on the masked image - that is the image that removes everything but the information contained within the largest contour.

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

It should be noted that the above code assumes you are using OpenCV 2.4.x. Take note that in OpenCV 3.x, the definition of cv2.drawContours has changed. Specifically, the output is a three element tuple output where the first image is the source image, while the other two parameters are the same as in OpenCV 2.4.x. Therefore, simply change the cv2.findContours statement in the above code to ignore the first output:

_, contours, _ = cv2.findContours(...) # Your call to find contours

这篇关于如何裁剪轮廓的内部区域?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆