我有这张图片:
我想在不影响图像内容的情况下使周围的黑色轮廓(边界)变白。 这是我使用的代码:
import cv2
image = cv2.imread('filename.jpg')
height, width, channels = image.shape
white = [255, 255, 255]
black = [0, 0, 0]
for x in range(0,width):
for y in range(0, height):
channels_xy = image[y, x]
if all(channels_xy == black):
image[y, x] = white
cv2.imwrite('result.jpg', image)
有没有建议在不影响图像内容的情况下更好地将边框变白为黑色?
答案 0 :(得分:1)
此代码可以提供帮助,但是非常慢。并且您需要为Python安装shapely软件包。
import cv2
import numpy as np
from pyutils_gph.utils import showIm
import shapely.geometry as shageo
from tqdm import tqdm, trange
img = cv2.imread('test.jpg')
cv2.imshow('src', img)
# get the gray image and do binaryzation
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
gray[gray < 100] = 0
gray[gray > 0] = 255
# get the largest boundry of the binary image to locate the target
contours, _ = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = cv2.minAreaRect(contours[0])
box = cv2.boxPoints(rect)
box = np.int0(box)
poly = shageo.Polygon(box)
minx = min(box[:, 0])
maxx = max(box[:, 0])
miny = min(box[:, 1])
maxy = max(box[:, 1])
h, w = img.shape[:2]
ind = np.zeros((h, w), np.bool)
# chech the point is inside the target or not
for i in trange(h):
for j in range(w):
if j < minx or j > maxx or i < miny or i > maxy:
ind[i, j] = True
else:
p = shageo.Point(j, i)
if not p.within(poly):
ind[i, j] = True
# make outside point to be white
img[ind] = (255, 255, 255)
cv2.imshow('res', img)
cv2.waitKey(0)
答案 1 :(得分:1)
经过研究,我最终找到了一个更快的解决方案(基于公认的答案)。这是代码:
# import packages
import numpy
import mahotas.polygon
import shapely.geometry as shageo
import cv2
import numpy as np
def get_mask(dims, pts):
# create a numpy array of zeros with the same dimensions of the image
canvas = numpy.zeros((dims[0], dims[1]), dtype=int)
# the points coords in the form of pt(y, x)
# fill the polygon with ones.
mahotas.polygon.fill_polygon(pts, canvas)
return canvas
def find_polygon(img):
# get the gray image and do binaryzation
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
gray[gray < 20] = 0
gray[gray > 0] = 255
# get the largest boundry of the binary image to locate the target
contours, _ = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = cv2.minAreaRect(contours[0])
box = cv2.boxPoints(rect)
box = np.int0(box)
poly = shageo.Polygon(box)
# return the polygone coords in a list
return list(poly.exterior.coords)
def main():
img = cv2.imread('filename.jpg')
# get the coords of the polygon containing (around) the image.
coords = find_polygon(img)
poly_coords = []
# the coords are floats and sometimes are negaive (-1), so transform them into positive ints.
# the mahotas.polygon.fill_polygon function accepts the coords in the form of pt(y, x) so the coords should be reversed
for element in coords:
poly_coords.append(tuple(map(int, map(abs, reversed(element)))))
mask = get_mask(img.shape, poly_coords)
# convert the mask into array of 0 and 1.
binary_mask = np.logical_not(mask).astype(int)
# reshape the array to be similar to the image dimenstions
binary_mask = binary_mask.reshape(img.shape[0], img.shape[1], -1)
# sum the binary mask with the image
cv2.imwrite('res.jpg', img + binary_mask * 255)
main()
积分:
1- Drawing polygons in numpy arrays
2- Whiten black contours around a skewed image opencv