2017-02-09 1 views
0

У меня есть изображение, на котором я хочу наложить (наложить) несколько точек на определенные координаты. Я использовал zorder и plt.scatter.Удалите пробелы вокруг изображения matplotlib с наложенным разбросом для сохранения в исходном размере

Я хочу, чтобы сохранить получившийся файл в оригинального размера к numpy array variable в Python и не в автономном режиме в файл (растровый формат), потому что я хочу, чтобы дополнительно обработать это изображение с разбросом участками на вершине без повторного прочтения ,

Мое мышление является то, что это будет быстрее, чтобы сохранить наложенное изображение в ( формат в RGB изображения - (height,width,channels)) в numpy array variable в Python, чем использовать plt.savefig, а затем перечитать изображение снова с cv2.imread затем выполните необходимой последующей обработки.

Скорость - важный фактор в моем случае.

Я попытался установить пределы оси, àxis.('off'), fig.tight_layout(pad=0), `bbox_inches = 0 /«жесткой»для того, чтобы избавиться от любого завершающим пространства вокруг моего наложенного изображения, НО:

  1. есть еще задняя серое пространство вокруг моего изображения (отображается, когда IMG будет отображаться cv2.imshow или cv2.imwrite)
  2. если plt.savefig используется -> белое пространство вокруг изображения появляется

  3. после преобразования в numpy array с наложенным изображением у него нет оригинального размера.

Код ниже, предложения приветствуются. Все прокомментированные слова представляют то, что я пробовал и не работал. Я оставил их там, чтобы люди больше не предлагали их.

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

img = cv2.imread('Lenna.png') 

h, w ,ch = np.shape(img) 

# some random coordinate points 
x = [30,40, 45, 60] 
y = [50,60, 65, 70] 

fig = plt.figure() 

# tried to set the axes, with these commands, didn't work 
#ax = plt.axes([0,0,1,1]) 
#fig_axes = fig.add_subplot(111) 


plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB), zorder=0, extent=[0,w, h, 0], interpolation="nearest") 
plt.scatter(x, y, zorder=1, facecolors='b', edgecolors='k', s=50) 

# tried to limit the axes size based on the image --> didn't work 
#plt.xlim(0,w) 
#plt.ylim(0,h) 

plt.axis('off') 

# again didn't do anything 
#fig.axes.get_xaxis().set_visible(False) 
#fig.axes.get_yaxis().set_visible(False) 


fig.tight_layout(pad=0) 
fig.canvas.draw() 

# save just for verification purpose that no space around the image is shown 
plt.savefig("test_Lenna_scatter.png", bbox_inches=0) 

# HERE I SAVE THE PLOTTED FIG IMAGE TO NUMPY ARRAY 
data_img_array = np.fromstring(fig.canvas.tostring_rgb(), dtype=np.uint8, sep='') 
data_img_array = data_img_array.reshape(fig.canvas.get_width_height()[::-1] + (3,)) 

# HERE I DISPLAY THE NUMPY ARRAY IMAGE AFTER SCATTER 
# ALSO PLOT ORIG IMG TO CHECK SIMILARITY 
cv2.imwrite('Lenna_scatter.png', cv2.cvtColor(data_img, cv2.COLOR_BGR2RGB)) 
cv2.imshow('Lenna Scatter', cv2.cvtColor(data_img, cv2.COLOR_BGR2RGB)) 
cv2.imshow('orig', img) 
cv2.waitKey(0) 
cv2.destroyAllWindows() 

РЕЗУЛЬТАТЫ

Наложенные изображения с Scatter участков, полученных из plt.savefig. Появляется пробел (если вы нажимаете на картинку), который я не хочу. overlaid image Image reconstructed numpy array

Image реконструированы numpy array после plt.scatter. сохранен с cv2.imwrite. Обратите внимание на серое конечное пространство и разный размер изображения. Который я не хочу.

+0

"ничего не получалось" не является достаточным описание проблемы. В коде, который вы показываете, вы не пытаетесь сохранить что-либо как массив numpy. Так что непонятно, что вы пытаетесь сделать. Пожалуйста, четко укажите, какой код вы используете, в результате чего получаете и насколько это отличается от вашего ожидания. Пожалуйста, сделайте это, отредактировав свой вопрос. – ImportanceOfBeingErnest

+0

'data_img' - это массив numpy (dtype = np.uint8), и это изображение RGB. ничего не работало -> до этого я точно указываю, что я пробовал, и я имел в виду, что ни одна из этих команд не имела никакого эффекта. – Roxanne

ответ

0

Чтобы создать фигуру без рамки в matplotlib, используйте plt.axes([0,0,1,1]) или fig.add_axes([0,0,1,1]), что сделает оси крупнее фигуры.

Поскольку вы хотите построить изображение с квадратными пикселями, сам рисунок должен, конечно, иметь тот же аспект, что и изображение. Разумным способом сделать это - установить figsize=(w/100.,h/100.), dpi=100, где w и h - размеры изображения.

При сохранении файла вам нужно выбрать одинаковые точки на дюйм, как вы выбрали при создании фигуры. Остальное должно быть самоочевидным.

import numpy as np 
import matplotlib.pyplot as plt 

img = plt.imread("https://i.stack.imgur.com/9qe6z.png") 
h, w ,ch = np.shape(img) 

x = [30,40, 45, 60] 
y = [50,60, 65, 70] 

fig = plt.figure(figsize=(w/100.,h/100.), dpi=100) 
ax = fig.add_axes([0,0,1,1]) 
ax.axis('off') 

ax.imshow(img, zorder=0, extent=[0,w, h, 0], interpolation="nearest") 
ax.scatter(x, y, zorder=1, facecolors='b', edgecolors='k', s=50) 

plt.savefig(__file__+".png", bbox_inches=0, dpi=100) 

img_recovered = plt.imread(__file__+".png") 
print img_recovered.shape 

В окне, показанном на экране может иметь небольшую границу, но сохраненное изображение имеет тот же размер, что и исходное изображение.

enter image description here

Смежные вопросы