我对Python完全陌生,但我想做的是在图像中绘制一个区域然后进行分析。这应该在GUI内部完成。我的程序现在可以使用Lasso Selector绘制一个区域(感谢http://matplotlib.org/examples/event_handling/lasso_demo.html)并且顶点保存在一个numpy数组中。我希望将整个区域保存为数组(或矩阵)。是否有内置功能吗?我是否需要制作一个foor-loop和if-statements并循环遍历图像中的所有元素,并检查哪个元素在哪个内部,哪个元素不在内。如果是这种情况,我不知道怎么做,因为来自顶点数组的元素不是整数和不成对的(对于第45行,第3列中没有一个顶点)和第17列中的一个)。我使用了tkinter,matplotlib,numpy以及没有的东西..(有关于如何对矩形进行此类操作的课程教程,我无法将其应用于此区域。)
简而言之:我想要的是一个numpy数组,其中包含我所绘制区域内的所有元素及其像素值。程序应能够更改该区域,然后在旧图像中替换它。
from tkinter import *
from matplotlib.widgets import LassoSelector
import matplotlib.image as mpimg
from pylab import *
from matplotlib import path
from tkinter.filedialog import askopenfilename
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
global fig, v
fname = "bild3.png" #Starting with file
def onselect(verts):
global v, length_y
print(verts)
p = path.Path(verts) #path array of verts
print(v)
ind = p.contains_points(v)
root = tk.Tk()
# Creating two frames
topFrame = tk.Frame()
bottomFrame = tk.Frame()
topFrame.pack(side="top")
bottomFrame.pack(side="bottom")
# Create buttons
button_open = tk.Button(topFrame, text="Open image", command=lambda: selectIm())
button_draw = tk.Button(topFrame, text="Draw ROI")
button_quit = tk.Button(topFrame, text="Quit", command=root.quit)
button_clear= tk.Button(topFrame, text="Clear")
button_save = tk.Button(topFrame, text="Save")
# Place buttons
button_open.pack(side="left")
button_draw.pack(side="left")
button_quit.pack(side="right") #fill makes it fill the frame
button_save.pack(side="left")
button_clear.pack(side = "left")
# Set figure on canvas
fig = plt.figure() #displays image and creates figure object??
img = mpimg.imread(fname) #ndarray [rows [cols [rgb 3 val]]]
plt.imshow(img) #also needed to display image
ax = plt.gca() #Axlarna hänger med ..
canvas = FigureCanvasTkAgg(fig, bottomFrame)
canvas.show()
canvas.get_tk_widget().pack(side='top', fill='both', expand=1)
lasso = LassoSelector(ax, onselect) #Should be in draw-function
def selectIm():
# global fig,
global v, length_y
print("Hej")
fname=askopenfilename()
img = mpimg.imread(fname)
plt.imshow(img) #does this overwrite or plot another one?
canvas.show() #updates canvas, or overwrites?
length_y=img.shape[0] #Number of rows
length_x=img.shape[1] #Number of cols
v = np.zeros((length_x*length_y, 2), dtype=np.int) #Creates zero array
#For y
a = np.array(range(0,length_x))
y = np.tile(a, length_y)
#For x
b = np.array(range(0,length_y))
x = np.repeat(b, length_x)
v[:,0] = x
v[:,1] = y
root.title("Ett nytt test")
root.mainloop()
在给出的链接(http://matplotlib.org/examples/event_handling/lasso_demo.html)中的示例中,我怀疑以下几行可以解决这个问题,但我并不了解include = False。同样在我的课程中,我没有这么好的结构,因为我现在对课程,对象等都不了解。这更像是一个图像分析项目。
class Datum(object):
colorin = colorConverter.to_rgba('red')
colorout = colorConverter.to_rgba('blue')
def __init__(self, x, y, include=False):
self.x = x
self.y = y
if include: self.color = self.colorin
else: self.color = self.colorout
感谢您对此问题的任何输入!
答案 0 :(得分:4)
我使用您脚本的某些部分提出了以下解决方案:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import LassoSelector
from matplotlib import path
fig = plt.figure()
ax1 = fig.add_subplot(121)
ax1.set_title('lasso selection:')
ax1.plot()
ax1.set_xlim([0, 10])
ax1.set_ylim([0, 10])
ax1.set_aspect('equal')
# Empty array to be filled with lasso selector
array = np.zeros((10,10))
ax2 = fig.add_subplot(122)
ax2.set_title('numpy array:')
msk = ax2.imshow(array, origin='lower',vmax=1, interpolation='nearest')
ax2.set_xlim([-1, 10])
ax2.set_ylim([-1, 10])
# Pixel coordinates
pix = np.arange(10)
xv, yv = np.meshgrid(pix,pix)
pix = np.vstack( (xv.flatten(), yv.flatten()) ).T
def updateArray(array, indices):
lin = np.arange(array.size)
newArray = array.flatten()
newArray[lin[indices]] = 1
return newArray.reshape(array.shape)
def onselect(verts):
global array, pix
p = path.Path(verts)
ind = p.contains_points(pix, radius=1)
array = updateArray(array, ind)
msk.set_data(array)
fig.canvas.draw_idle()
lasso = LassoSelector(ax1, onselect)
plt.show()