You can use OpenCV Contours and masking algorithms
and by using Bitwise AND operation
between this bounding rectangle(counter) and mask
, we can crop out polygon from Image.
Here are few points to look at before taking and running this code.
Links are for images
cv2.boundingRect => It will create bounding rectangle look at image for best visualization
With and Without Bounding Rectangle
cv2.drawContours => It will update mask where ever points lie inside our counter.
Mask with and Without Contours extract
cv2.bitwise_and => For this you can refer to :
Stackoverflow Discussion over cv2.bitwise_and(img,img,mask = mask)
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as img
import matplotlib.patches as patches
import cv2
image_file = 'photo.jpg'
def selection(s):
plt.title(s, fontsize=16)
plt.axis('off')
plt.draw()
# ========= Saving Click Point using ginput method =========
while True:
data = []
while len(data) < 3:
image = img.imread(image_file)
fig, ax=plt.subplots()
ax.imshow(image,cmap="gray")
selection('Free Form Selection')
data = np.asarray(plt.ginput(0, timeout=-1))
if len(data) < 3:
selection('Free Form Selection')
# ========= Counter-Dimension =========
minXY = data.min(axis= 0)
maxXY = data.max(axis= 0)
delXY = maxXY - minXY
# ========= Counter with Free-Form Selection =========
counter = plt.fill(data[:, 0], data[:, 1], '#f0f0f0', edgecolor='#000000', linewidth= 0.5)
rect = patches.Rectangle(minXY, delXY[0], delXY[1], linewidth= 0.5, edgecolor='#000000', facecolor="none")
# ========= Add the patch to the Axes =========
ax.add_patch(rect)
selection(' ')
if plt.waitforbuttonpress():
break
# Get rid of fill
for c in counter:
c.remove()
# ========= Saving Point of Polygon to CSV file =========
np.savetxt('data.csv', data, delimiter=',')
# ========= Using OpenCV We can crop polygon of Image =========
img = cv2.imread(image_file)
pts = np.array(data, dtype='int32') # => datatype should be int32
# ========= Crop the Bounding Rectangle =========
rect = cv2.boundingRect(pts)
x,y,w,h = rect
croped = img[y:y+h, x:x+w].copy()
# ========= Making 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)
# ========= BitWise Operation =========
dst = cv2.bitwise_and(croped, croped, mask=mask)
# ========= Final Result =========
cv2.imwrite("dst.png", dst)
img = cv2.imread('dst.png')
cv2.imshow('Image', img)
cv2.waitKey(0)