【问题标题】:How to crop an image along major axis of the blob/contour with a rectangular bounding box using Python如何使用 Python 沿着带有矩形边界框的斑点/轮廓的主轴裁剪图像
【发布时间】:2020-10-26 05:51:24
【问题描述】:

我想裁剪一张带有手绘橙色高亮区域的图像,如下所示,

结果应该是沿着斑点或轮廓的长轴裁剪的图像,带有一个矩形边界框,如下所示,

这是我尝试过的,

import numpy as np
import cv2

# load the image
image = cv2.imread("frame50.jpg", 1)

#color boundaries [B, G, R]
lower = [0, 3, 30]
upper = [30, 117, 253]

# create NumPy arrays from the boundaries
lower = np.array(lower, dtype="uint8")
upper = np.array(upper, dtype="uint8")

# find the colors within the specified boundaries and apply
# the mask
mask = cv2.inRange(image, lower, upper)
output = cv2.bitwise_and(image, image, mask=mask)

ret,thresh = cv2.threshold(mask, 50, 255, 0)
if (int(cv2.__version__[0]) > 3):
    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
else:
    im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

if len(contours) != 0:
    # find the biggest countour (c) by the area
    c = max(contours, key = cv2.contourArea)
    x,y,w,h = cv2.boundingRect(c)
    ROI = image[y:y+h, x:x+w]
cv2.imshow('ROI',ROI)
cv2.imwrite('ROI.png',ROI)

cv2.waitKey(0)

这似乎大部分时间都不起作用。对于某些图像,会发生以下情况,

我想知道是否有更好的方法来解决这个问题,或者我如何解决我现在拥有的问题。请注意,突出显示的区域是手绘的,可以是任何形状,但它是关闭的,而不是打开的在所有情况下,高光的颜色都是橙色本身的阴影。 有没有办法只保留圈内的内容而将圈外的所有内容都涂黑?

EDIT1: 我能够通过更多地改变阈值来修复错误的剪辑。但我现在的主要问题是:有没有办法只保留圈内的内容而屏蔽圈外的所有内容?我可以看到如下所示的面具,

如何使用相同的矩形边界框填充此蒙版并保留圆圈内的内容并将其外的所有内容涂黑?

【问题讨论】:

    标签: python image opencv blob opencv-contour


    【解决方案1】:

    你试过了吗

    image[x:x+w, y:y+h]
    

    你能用下面的代码检查bbox吗

    cv2.rectangle(thresh,(x,y),(x+w,y+h),(255,0,0),2)
    

    【讨论】:

    • 谢谢,我把 bbox 线放在哪里?对不起,我是菜鸟
    • 有没有办法只保留圈内的内容而屏蔽圈外的所有内容?
    • 我确实尝试了 image[x:x+w, y:y+h],但这不是给出索引的方式。 image[y:y+h, x:x+w] 工作正常。
    • 抱歉回复晚了,对于bbox行,可以参考下面的链接geeksforgeeks.org/python-opencv-cv2-rectangle-method
    【解决方案2】:

    首先,使用 HSV 图像而不是 BGR 图像进行遮罩(提取颜色)总是更好。您可以通过以下代码做到这一点。

    HSV_Image = cv2.cvtColor(Image, cv2.COLOR_BGR2HSV)
    ThreshImage = cv2.inRange(HSV_Image, np.array([0, 28, 191]), np.array([24, 255, 255]))
    

    在这种情况下,这里的范围数字是橙色的。

    Image 是输入图像,ThreshImage 是输出图像,橙色区域为白色,其他所有区域为黑色。

    现在使用 cv2.RETR_EXTERNAL 标志在 ThreshImage 中查找轮廓将只给出一个轮廓,即橙色区域的外边界。

    Contours, Hierarchy = cv2.findContours(ThreshImage, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    

    裁剪橙色区域:

    BoundingRect = cv2.boundingRect(Contours[0])
    (x, y, w, h) = BoundingRect
    CroppedImage = Image[y:y+h, x:x+w].copy()
    

    “CroppedImage”将根据需要存储裁剪的橙色区域。

    仅获取轮廓内的内容:

    在这里,按位与运算将很有用,因为我们已经检测到了轮廓。

    首先,我们必须创建一个与输入图像形状相同的黑色图像,并绘制填充有白色的轮廓。

    ContourFilledImage = np.zeros(Image.shape, dtype=np.uint8)
    cv2.drawContours(ContourFilledImage, Contours, -1, (255, 255, 255), -1)
    

    现在对输入图像和“ContourFilledImage”执行按位与运算

    OnlyInnerData = cv2.bitwise_and(ContourFilledImage, Image)
    

    “OnlyInnerData”图像是所需的输出图像,只有圆圈内的内容。

    【讨论】:

      猜你喜欢
      • 2021-07-12
      • 2012-03-20
      • 2019-01-31
      • 1970-01-01
      • 1970-01-01
      • 2014-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多