Как удалить несколько полигонов с помощью Opencv Python - PullRequest
0 голосов
/ 18 марта 2019

Привет команда StackOverflow,

У меня есть изображение, и я хочу удалить из него много частей / частей.Я попытался использовать приведенный ниже код, взятый из Обрезка вогнутого многоугольника из изображения с использованием Opencv Python

Предположим, у меня есть это изображение Lena Image.Кроме того, у меня есть несколько многоугольников (таких как прямоугольные формы или многоугольники любой формы) из изображения, полученного с помощью инструмента аннотации 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)

Используя Лену, у меня есть этот вывод dst2 image.Но мне нужно пойти дальше и отбелить другие точки / многоугольники, например, глаза.

Как видите, мой код может использовать только одну точку многоугольника.Я попытался добавить две другие точки многоугольника в моем случае двумя глазами и получил dst2.

Добавляя, я имею в виду, что я добавил многомерные точки (например, pts = np.array (a + b + c)).

Короче говоря, наличие изображения - это короткий способ удалить эти многоугольники из изображения (сохраняя размеры изображения), используя OpenCV и python.

Файл Json: https://drive.google.com/file/d/1UyOYUVMHpu2vBBEdR99bwrRX5xIfdOCa/view?usp=sharing

Ответы [ 2 ]

1 голос
/ 20 марта 2019

Вам нужно будет использовать цикл, чтобы пройти все точки в файле 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, который вы связали здесь, для достижения этого.

enter image description here

0 голосов
/ 29 марта 2019

Я хотел бы поделиться с вами моим ожидаемым решением, которое является немного измененной версией ответа @Shawn Mathew.

Исходное изображение:

enter image description here

Код:

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

enter image description here

Цвет изображения изменился из-за Matplotlib, если вы хотите сохранить цвет, сохраните изображение с помощью cv2.imwrite

...