Cómo recortar un polígono cóncavo de una imagen usando Opencv python

¿Cómo puedo recortar un polígono cóncavo de una imagen. Mi imagen de entrada se parece a esta .

y las coordenadas del polígono cerrado son [10,150], [150,100], [300,150], [350,100], [310,20], [35,10]. Quiero que la región delimitada por un polígono cóncavo se recorte utilizando opencv. Busqué otras preguntas similares pero no pude encontrar la respuesta correcta. ¿Por eso lo pregunto? Me puedes ayudar.

Cualquier ayuda sería muy apreciada.!!!

Pasos

  1. encuentra la región usando los puntos poli
  2. crear máscara utilizando los puntos poli
  3. enmascarar op para recortar
  4. agrega bg blanco si es necesario

El código:

# 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) 

Imagen de origen:

introduzca la descripción de la imagen aquí

Resultado:

introduzca la descripción de la imagen aquí

Puedes hacerlo en 3 pasos:

1) Crear una máscara fuera de la imagen.

 mask = np.zeros((height, width)) points = np.array([[[10,150],[150,100],[300,150],[350,100],[310,20],[35,10]]]) cv2.fillPoly(mask, points, (255)) 

2) Aplicar máscara a la imagen original.

 res = cv2.bitwise_and(img,img,mask = mask) 

3) Opcionalmente, puede eliminar el recorte de la imagen para tener una más pequeña.

 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]] 

Con esto deberías tener al final la imagen recortada.

ACTUALIZAR

Para completar, aquí está el código completo:

 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)