代码之家  ›  专栏  ›  技术社区  ›  Himanshu Tiwari

使用Opencv python从图像中裁剪凹多边形

  •  22
  • Himanshu Tiwari  · 技术社区  · 7 年前

    如何从图像中裁剪凹多边形。我的输入图像看起来像 this .

    以及 关闭 多边形是 [10,150],[150,100],[300,150],[350,100],[310,20],[35,10]. 我希望使用opencv裁剪以凹多边形为边界的区域。我搜索了其他类似的问题,但没有找到正确的答案。这就是为什么我要问这个问题?你能帮助我吗。

    任何帮助都将不胜感激。!!!

    3 回复  |  直到 7 年前
        1
  •  47
  •   Community CDub    4 年前

    步骤

    1. 使用多边形点查找区域
    2. 使用多边形点创建遮罩
    3. 进行遮罩操作以裁剪
    4. 如果需要,添加白色背景

    # 2018.01.17 20:39:17 CST
    # 2018.01.17 20:50:35 CST
    import numpy as np
    import cv2
    
    img = cv2.imread("test.png")
    pts = np.array([[10,150],[150,100],[300,150],[350,100],[310,20],[35,10]])
    
    ## (1) Crop the bounding rect
    rect = cv2.boundingRect(pts)
    x,y,w,h = rect
    croped = img[y:y+h, x:x+w].copy()
    
    ## (2) make mask
    pts = pts - pts.min(axis=0)
    
    mask = np.zeros(croped.shape[:2], np.uint8)
    cv2.drawContours(mask, [pts], -1, (255, 255, 255), -1, cv2.LINE_AA)
    
    ## (3) do bit-op
    dst = cv2.bitwise_and(croped, croped, mask=mask)
    
    ## (4) add the white background
    bg = np.ones_like(croped, np.uint8)*255
    cv2.bitwise_not(bg,bg, mask=mask)
    dst2 = bg+ dst
    
    
    cv2.imwrite("croped.png", croped)
    cv2.imwrite("mask.png", mask)
    cv2.imwrite("dst.png", dst)
    cv2.imwrite("dst2.png", dst2)
    

    源图像:

    enter image description here

    结果:

    enter image description here

        2
  •  15
  •   api55    4 年前

    您可以通过三个步骤完成:

    1. 在图像外创建遮罩

      掩码=np。零((高度、宽度)) cv2.fillPoly(遮罩,点,(255))

    2. 将遮罩应用于原始图像

      res=cv2。按位与(img,img,mask=mask)

    3. (可选)您可以删除裁剪图像以获得较小的图像

      rect=cv2。boundingRect(points)#返回矩形的(x、y、w、h) 裁剪=res[rect[1]:rect[1]+rect[3]、rect[0]:rect[0]+rect[2]]

    这样,您应该在最后裁剪图像

    更新

    为了完整起见,以下是完整的代码:

    import numpy as np
    import cv2
    
    img = cv2.imread("test.png")
    height = img.shape[0]
    width = img.shape[1]
    
    mask = np.zeros((height, width), dtype=np.uint8)
    points = np.array([[[10,150],[150,100],[300,150],[350,100],[310,20],[35,10]]])
    cv2.fillPoly(mask, points, (255))
    
    res = cv2.bitwise_and(img,img,mask = mask)
    
    rect = cv2.boundingRect(points) # returns (x,y,w,h) of the rect
    cropped = res[rect[1]: rect[1] + rect[3], rect[0]: rect[0] + rect[2]]
    
    cv2.imshow("cropped" , cropped )
    cv2.imshow("same size" , res)
    cv2.waitKey(0)
    

    对于彩色背景版本,请使用如下代码:

    import numpy as np
    import cv2
    
    img = cv2.imread("test.png")
    height = img.shape[0]
    width = img.shape[1]
    
    mask = np.zeros((height, width), dtype=np.uint8)
    points = np.array([[[10,150],[150,100],[300,150],[350,100],[310,20],[35,10]]])
    cv2.fillPoly(mask, points, (255))
    
    res = cv2.bitwise_and(img,img,mask = mask)
    
    rect = cv2.boundingRect(points) # returns (x,y,w,h) of the rect
    im2 = np.full((res.shape[0], res.shape[1], 3), (0, 255, 0), dtype=np.uint8 ) # you can also use other colors or simply load another image of the same size
    maskInv = cv2.bitwise_not(mask)
    colorCrop = cv2.bitwise_or(im2,im2,mask = maskInv)
    finalIm = res + colorCrop
    cropped = finalIm[rect[1]: rect[1] + rect[3], rect[0]: rect[0] + rect[2]]
    
    cv2.imshow("cropped" , cropped )
    cv2.imshow("same size" , res)
    cv2.waitKey(0)
    
        3
  •  0
  •   jadekim    2 年前

    对于模糊图像背景版本,请使用如下代码:

        img = cv2.imread(img_path)
        box = <box points>
    
        # -- background
        blur_bg = cv2.blur(img, (h, w))
        mask1 = np.zeros((h, w, 3), np.uint8)
        mask2 = np.ones((h, w, 3), np.uint8) * 255
        cv2.fillPoly(mask1, box, (255, 255, 255))
    
        # -- indexing
        img_idx = np.where(mask1 == mask2)
        bg_idx = np.where(mask1 != mask2)
        
        # -- fill box
        res = np.zeros((h, w, 3), np.int64)
        res[img_idx] = img[img_idx]
        res[bg_idx] = blur_bg[bg_idx]
        res = res[y1:y2, x1:x2, :]