I draw this mask with cv2.drawContours
. I need edges to be round. How should I do it?
CodePudding user response:
You can do what Jeru Luke suggests in the comments. You need dilate, erode, dilate. Just Opening (erode, dilate) will only affect convex corners, same with Closing and concave corners.
kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (101,101))
out = cv.dilate(im, kernel)
out = cv.erode(out, kernel, iterations=2)
out = cv.dilate(out, kernel)
result vs. difference as (im >> 1) (out >> 1)
:
If your polygon has those 13 corners and it's literally a list of 13 points, then Hihikomori's answer will fail. I'll edit my answer to demonstrate... this is with 1 iteration instead of 120:
It fails because the contour isn't a dense list of points but merely the corners of the polygon. That approach requires points to have roughly equal spacing between them, and to be fairly dense.
CodePudding user response:
import cv2
import numpy as np
img = cv2.imread("path/to/image")
img_gray=img[:,:,0]
contours, hierarchy = cv2.findContours(img_gray, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
# Split contour data to components
contour=contours[0].reshape(contours[0].shape[0],-1).astype(np.float32)
cnt_len = contour.shape[0]
cnt_x= contour[:,0]
cnt_y= contour[:,1]
# Extend contour to preserve boundary conditions.
cnt_x = np.concatenate((cnt_x,cnt_x,cnt_x),axis=0)
cnt_y = np.concatenate((cnt_y,cnt_y,cnt_y),axis=0)
# Blurring the contour
amount = 120
for _ in range(amount):
cnt_x= np.convolve(cnt_x,[0.33,0.34,0.33],"same")
cnt_y= np.convolve(cnt_y,[0.33,0.34,0.33],"same")
# Composing contour to draw with opencv
convolved_cnt = np.empty((cnt_x.shape[0],2),np.int32)
convolved_cnt[:,0]=cnt_x
convolved_cnt[:,1]=cnt_y
convolved_cnt=convolved_cnt[cnt_len:cnt_len*2]
cv2.drawContours(img, [convolved_cnt], -1, (0,255,0), 3)
cv2.imshow("",img)
cv2.waitKey()