凹掩膜到凸
Concave mask to convex
我正在检测图像中的对象并根据轮廓创建蒙版。然后将面罩扩张并平滑。例如,从这样的图像:
我最终得到了这样的面具:
当我使用蒙版裁剪图像(椅子)时,我丢失了椅子腿之间的(背景)信息。为了解决这个问题,我想把这个凹面面具变成凸面面具。例如,进入这个(在 Photoshop 中创建):
我该怎么做?:
代码(show_mask.py):
import sys
from pathlib import Path
from helpers_cv2 import *
import cv2
import numpy
img_path = Path(sys.argv[1])
img = cmyk_to_bgr(str(img_path))
threshed = threshold(img, 240, type=cv2.THRESH_BINARY_INV)
contours = find_contours(threshed)
mask = mask_from_contours(img, contours)
mask_smooth = smooth_mask(mask, 51)
mask_dilate = dilate_mask(mask_smooth, 51)
mask_smooth = smooth_mask(mask_dilate, 51)
cv2.imshow("img", img)
cv2.imshow("mask_smooth", mask_smooth)
cv2.waitKey(0)
cv2.destroyAllWindows()
import os
from pathlib import Path
import math
import cv2
import numpy
from PIL import Image
from PIL import ImageCms
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
cwd = os.path.dirname(os.path.abspath(__file__))
def cmyk_to_bgr(cmyk_img):
img = Image.open(cmyk_img)
if img.mode == "CMYK":
img = ImageCms.profileToProfile(img, "\Color Profiles\USWebCoatedSWOP.icc", cwd + "\Color Profiles\sRGB_Color_Space_Profile.icm", outputMode="RGB")
return cv2.cvtColor(numpy.array(img), cv2.COLOR_RGB2BGR)
def threshold(img, thresh=128, maxval=255, type=cv2.THRESH_BINARY):
if len(img.shape) == 3:
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
threshed = cv2.threshold(img, thresh, maxval, type)[1]
return threshed
def find_contours(img):
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
morphed = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
contours = cv2.findContours(morphed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
return contours[-2]
def max_contour(contours):
return sorted(contours, key=cv2.contourArea)[-1]
def mask_from_contours(ref_img, contours):
mask = numpy.zeros(ref_img.shape, numpy.uint8)
mask = cv2.drawContours(mask, contours, -1, (255,255,255), -1)
return cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
def dilate_mask(mask, kernel_size=11):
kernel = numpy.ones((kernel_size, kernel_size), numpy.uint8)
dilated = cv2.dilate(mask, kernel, iterations=1)
return dilated
def smooth_mask(mask, kernel_size=11):
blurred = cv2.GaussianBlur(mask, (kernel_size, kernel_size), 0)
threshed = threshold(blurred)
return threshed
全尺寸图片和代码可以在repository.
中找到
在看到提到的 page ma3oun 之后,我设法让它工作了。我所要做的就是在我的代码中添加几行:
contours = find_contours(mask_smooth)
hull = []
for i in range(len(contours)):
hull.append(cv2.convexHull(contours[i], False))
hull = mask_from_contours(img, hull)
cv2.imshow("hull", hull)
输出图像:
代码(show_convex_hull.py):
import sys
from pathlib import Path
from helpers_cv2 import *
import cv2
import numpy
from pprint import pprint
img_path = Path(sys.argv[1])
img = cmyk_to_bgr(str(img_path))
threshed = threshold(img, 240, type=cv2.THRESH_BINARY_INV)
contours = find_contours(threshed)
mask = mask_from_contours(img, contours)
mask_smooth = smooth_mask(mask, 51)
mask_dilate = dilate_mask(mask_smooth, 51)
mask_smooth = smooth_mask(mask_dilate, 51)
# convex hull ops
# find contours from the mask (contours needs to be calculated again because the mask is updated)
contours = find_contours(mask_smooth)
# find and store hull points
hull = []
for i in range(len(contours)):
hull.append(cv2.convexHull(contours[i], False))
# create a mask from hull points
hull = mask_from_contours(img, hull)
cv2.imshow("hull", hull)
cv2.waitKey(0)
cv2.destroyAllWindows()
我正在检测图像中的对象并根据轮廓创建蒙版。然后将面罩扩张并平滑。例如,从这样的图像:
我最终得到了这样的面具:
当我使用蒙版裁剪图像(椅子)时,我丢失了椅子腿之间的(背景)信息。为了解决这个问题,我想把这个凹面面具变成凸面面具。例如,进入这个(在 Photoshop 中创建):
我该怎么做?:
代码(show_mask.py):
import sys
from pathlib import Path
from helpers_cv2 import *
import cv2
import numpy
img_path = Path(sys.argv[1])
img = cmyk_to_bgr(str(img_path))
threshed = threshold(img, 240, type=cv2.THRESH_BINARY_INV)
contours = find_contours(threshed)
mask = mask_from_contours(img, contours)
mask_smooth = smooth_mask(mask, 51)
mask_dilate = dilate_mask(mask_smooth, 51)
mask_smooth = smooth_mask(mask_dilate, 51)
cv2.imshow("img", img)
cv2.imshow("mask_smooth", mask_smooth)
cv2.waitKey(0)
cv2.destroyAllWindows()
import os
from pathlib import Path
import math
import cv2
import numpy
from PIL import Image
from PIL import ImageCms
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
cwd = os.path.dirname(os.path.abspath(__file__))
def cmyk_to_bgr(cmyk_img):
img = Image.open(cmyk_img)
if img.mode == "CMYK":
img = ImageCms.profileToProfile(img, "\Color Profiles\USWebCoatedSWOP.icc", cwd + "\Color Profiles\sRGB_Color_Space_Profile.icm", outputMode="RGB")
return cv2.cvtColor(numpy.array(img), cv2.COLOR_RGB2BGR)
def threshold(img, thresh=128, maxval=255, type=cv2.THRESH_BINARY):
if len(img.shape) == 3:
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
threshed = cv2.threshold(img, thresh, maxval, type)[1]
return threshed
def find_contours(img):
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
morphed = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
contours = cv2.findContours(morphed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
return contours[-2]
def max_contour(contours):
return sorted(contours, key=cv2.contourArea)[-1]
def mask_from_contours(ref_img, contours):
mask = numpy.zeros(ref_img.shape, numpy.uint8)
mask = cv2.drawContours(mask, contours, -1, (255,255,255), -1)
return cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
def dilate_mask(mask, kernel_size=11):
kernel = numpy.ones((kernel_size, kernel_size), numpy.uint8)
dilated = cv2.dilate(mask, kernel, iterations=1)
return dilated
def smooth_mask(mask, kernel_size=11):
blurred = cv2.GaussianBlur(mask, (kernel_size, kernel_size), 0)
threshed = threshold(blurred)
return threshed
全尺寸图片和代码可以在repository.
中找到在看到提到的 page ma3oun 之后,我设法让它工作了。我所要做的就是在我的代码中添加几行:
contours = find_contours(mask_smooth)
hull = []
for i in range(len(contours)):
hull.append(cv2.convexHull(contours[i], False))
hull = mask_from_contours(img, hull)
cv2.imshow("hull", hull)
输出图像:
代码(show_convex_hull.py):
import sys
from pathlib import Path
from helpers_cv2 import *
import cv2
import numpy
from pprint import pprint
img_path = Path(sys.argv[1])
img = cmyk_to_bgr(str(img_path))
threshed = threshold(img, 240, type=cv2.THRESH_BINARY_INV)
contours = find_contours(threshed)
mask = mask_from_contours(img, contours)
mask_smooth = smooth_mask(mask, 51)
mask_dilate = dilate_mask(mask_smooth, 51)
mask_smooth = smooth_mask(mask_dilate, 51)
# convex hull ops
# find contours from the mask (contours needs to be calculated again because the mask is updated)
contours = find_contours(mask_smooth)
# find and store hull points
hull = []
for i in range(len(contours)):
hull.append(cv2.convexHull(contours[i], False))
# create a mask from hull points
hull = mask_from_contours(img, hull)
cv2.imshow("hull", hull)
cv2.waitKey(0)
cv2.destroyAllWindows()