Добавление изображений по заданным c координатам (OpenCV, matplotlib) - PullRequest
0 голосов
/ 04 февраля 2020

У меня есть изображение с координатами указанных c пятен, которые должны быть заменены определенными изображениями. Координаты представлены в виде массива 3D numpy с произвольной формой, где 1-е измерение - это различные классы изображений. Plotting array[1, :,].

Как мне подойти к этому?

1 Ответ

1 голос
/ 04 февраля 2020

Пожалуйста, посмотрите на приведенный ниже код

import cv2
import numpy as np
from skimage import measure


def resize_image(img,size):
    img = cv2.resize(img,(img.shape[0],size[1]),interpolation = cv2.INTER_AREA)
    img = cv2.resize(img,size,interpolation = cv2.INTER_AREA)
    return img


FINAL_TILE_WIDTH = 8

#loading image
tile_mask = cv2.imread("tile.png")
tile_mask = cv2.cvtColor(tile_mask, cv2.COLOR_BGR2GRAY)
tile_mask = resize_image(tile_mask,(36,FINAL_TILE_WIDTH))

img = cv2.imread("image.png")
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img[img < 127] = 0
img[img != 0] = 255

#final image will be stored here
final_image = np.zeros(img.shape).astype(np.uint8)


#perform connected components on the image
img = measure.label(img).astype(np.uint8)

labels = np.unique(img)

#removing noise detections
for i in labels:
    if i != 0:
        if len(np.where(img == i)[0]) < 30:
            img[img == i] = 0

img[img != 0] = 255

#extracting the contours of all the rectangles. They might not completely be rectangles.
#but the following operation will make sure everything works fine.
_,cnts,_ = cv2.findContours(img.copy(), cv2.RETR_EXTERNAL,
    cv2.CHAIN_APPROX_SIMPLE)

#iterate trough each contour detected
for cnt in cnts:
    #extract the extreme points, here the assumption of rectangles oriented along axis is taken.
    (minX ,minY)= np.min(cnt,axis = 0)[0]
    (maxX, maxY) = np.max(cnt,axis = 0)[0]
    width = maxX - minX
    width = width - width%2
    height = maxY - minY
    height = height - height%2
    center = (int((maxX+minX)/2),int((maxY+minY)/2))
    #find if width is higher or height is higher. This will be used to orient the tile vertically or horizontally.
    orientation = (width > height)
    temp_tile_mask = []
    tile_width = 0
    tile_height = 0
    #change the orientation of the tile
    if orientation:
        temp_tile_mask = tile_mask
        tile_width = width
        tile_height = FINAL_TILE_WIDTH
        temp_tile_mask = resize_image(temp_tile_mask,(tile_width, tile_height))
    else:
        temp_tile_mask = np.transpose(tile_mask)
        tile_width = FINAL_TILE_WIDTH
        tile_height = height
        temp_tile_mask = resize_image(temp_tile_mask,(tile_width, tile_height))
    #apply the tile to the final image
    final_image[center[1]-int(tile_height/2):center[1]+int(tile_height/2),
                center[0]-int(tile_width/2):center[0]+int(tile_width/2)] = temp_tile_mask[:,:]


cv2.imshow("img", final_image)
cv2.waitKey(0)

The Final Image

На самом деле я не работал над какой-либо оптимизацией, просто пришел к требованию. Также на изображении выше, плитки выглядят очень сглаженными, для решения этой проблемы можно изменить некоторые размеры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...