【问题标题】:How to remove multiple polygons using Opencv python如何使用 Opencv python 删除多个多边形
【发布时间】:2019-08-08 07:17:07
【问题描述】:

您好 StackOverflow 团队,

我有一张图片,我想从图片中删除许多部分/部分。我尝试使用以下代码取自Cropping Concave polygon from Image using Opencv python

假设我有这张图片。此外,我从通过 lebelme 注释工具获得的图像中获得了多个多边形(例如矩形或任何形式的多边形)。所以,我想从图像中删除这些形状,或者只是将它们的像素更改为白色。

换句话说,Labelme Tool 会给你一个字典文件,其中字典有一个由每个部分/多边形/形状的点组成的键)

然后可以很容易地从字典文件中提取多边形点。提取点后,我们可以通过命名来定义我们的点(例如a,b,s...h),每个点都是这种多维格式“[[1526, 319], [1526, 376], [1593 , 379], [1591, 324]]"

在这里我想到了美白每个区域。但是多维数组的白化似乎不可靠。

import numpy as np
import cv2
import json

with open('ann1.json') as f:
    data = json.load(f)

#%%
a = data['shapes'][0]['points']; b = data['shapes'][1]['points']; c = data['shapes'][2]['points']; 
#%%
img = cv2.imread("lena.jpg")
pts = np.array(a) # Points

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

使用 Lena 我有这个输出 。 但我需要更进一步并美白其他点/多边形,例如眼睛。

如您所见,我的代码只能使用一个多边形点。我尝试在两只眼睛的情况下附加另外两个多边形点并得到

通过附加,我的意思是我添加了多维点(例如 pts = np.array(a+b+c))。

简而言之,有一个图像是一种使用 OpenCV 和 python 从图像中删除这些多个多边形(通过保持图像的尺寸)的捷径。

Json 文件: https://drive.google.com/file/d/1UyOYUVMHpu2vBBEdR99bwrRX5xIfdOCa/view?usp=sharing

【问题讨论】:

  • 您能否编辑并添加具有预期输出的示例图像?目前,描述不是特别清楚。我认为您可能只是想组合多个掩码,“按位或”应该实现。
  • 您的意思是要遍历每组点并删除该多边形?
  • 谢谢,@AlexanderReynolds...我已经编辑了这个问题。让我知道是否需要进一步编辑
  • @ShawnMathew。谢谢..我的目的是通过保持图像的尺寸来删除每个多边形。循环遍历这些点可以实现吗?
  • 请也分享您的 JSON 文件。

标签: python opencv image-processing computer-vision mask


【解决方案1】:

您需要使用 to 循环遍历 JSON 文件中的所有点。我已编辑您的代码以反映这一点。

import cv2
import json
import matplotlib.pyplot as plt
import numpy as np

img_path =r"/path/to/lena.png"
json_path = r"/path/to/lena.json"

with open(json_path) as f:
   data = json.load(f)


img = cv2.imread(img_path)

for idx in np.arange(len(data['shapes'])):
    if idx == 0:  #can remove this
        continue  #can remove this
    a = data['shapes'][idx]['points']
    pts = np.array(a) # Points

    ## (1) Crop the bounding rect
    rect = cv2.boundingRect(pts)
    print(rect)
    x,y,w,h = rect
    img[y:y+h, x:x+w] = (255, 255, 255)

    plt.imshow(img)
    plt.show()

输出: 我忽略了第一行,因为它没有很好地可视化结果。我带头使用矩形而不是多边形。如果您需要多边形,则需要使用类似 cv2.drawContours()cv2.polylines()cv2.fillPoly() 的东西,正如您在此处链接的 SO 答案中所建议的那样,来实现它。

【讨论】:

  • 谢谢。您的代码仅输出眼睛(裁剪的眼睛),而不是输出没有两只眼睛的整个图像。也许我们需要为图像执行另一个循环。你怎么看?
  • 我以为你会在这方面工作......我想我可以发布一个更新来完整地回答你的问题......
  • 您的代码只删除了两只眼睛(不知何故使两只眼睛变白)。但是,如果你回到我上面的问题,我分享了三张图片。第一个图像是原始图像。然后,使用第一个多边形点(在我的情况下为 a)我实现了第二个图像(这是我想要的)。然后我想从第二张图像走得更远,例如,去除任何其他具有多边形形状的眼睛。我需要通过保持图像尺寸相同来同时进行所有这些过程。如您所见,在我的第三张图片中,我需要走得更远,但得到了一张凌乱的图片。
  • 此代码会将区域删除为矩形,一个接一个。如果你想要多边形,你需要像我提到的那样使用cv2.fillPoly()。如果要保持原始图像的大小,则必须将颜色更改为白色。你还会如何“移除”该区域?您是在谈论像PNG图像这样的透明背景吗?您已经拥有执行此操作的代码。为什么不把它们结合起来呢?
【解决方案2】:

我想与您分享我预期的解决方案,它是@Shawn Mathew 答案的一些修改版本。

输入图片:

代码:

with open('lena.json') as f:
    json_file = json.load(f)
img = cv2.imread("folder/lena.jpg")
for polygon in np.arange(len(json_file['shapes'])):
    pts = np.array(json_file['shapes'][polygon]['points'])
# If your polygons are rectangular, you can fill with white color to the areas you want be removed by uncommenting the below two lines
#   x,y,w,h = cv2.boundingRect(pts) 
#    cv2.rectangle(img, (x, y), (x+w, y+h), (255, 255, 255), -1)
# if your polygons are different shapes other than rectangles you can just use the below line
    cv2.fillPoly(img, pts =[pts], color=(255,255,255))

plt.imshow(img)
plt.show()

由于 Matplotlib 导致图像颜色发生变化,如果要保留颜色使用 cv2.imwrite 保存图像

【讨论】:

  • 您可以使用 plt.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB));plt.show() 使用 matplotlib 以原始颜色查看图像。这是因为 opencv 使用 BGR 通道排序,而其他人使用 RGB
猜你喜欢
  • 1970-01-01
  • 2015-01-16
  • 2023-04-06
  • 1970-01-01
  • 2020-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多