我正在尝试创建一些图像分析代码,我要求用户在图像上绘制线条或曲线,然后记录沿该线条的像素强度。我希望能够改变线条的粗细并沿宽度取像素的平均值来给出线条每个点的强度平均值,我不确定如何做到这一点。在视觉上我可以改变图上线条的粗细,但它不会影响所选像素的数量/数量。我已经包含了以下代码的示例。
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import sys
"""This class is a modification of the code created by Joerg Doepfert 2014 based on code posted by Daniel
Kornhauser. Which can be found at https://github.com/jdoepfert/roipoly.py /blob/master/roipoly.py """
class roipoly:
def __init__(self, fig=[], ax=[], roicolor='b',thickness=2):
if fig == []:
fig = plt.gcf()
if ax == []:
ax = plt.gca()
self.previous_point = []
self.allxpoints = []
self.allypoints = []
self.start_point = []
self.end_point = []
self.line = None
self.roicolor = roicolor
self.thickness = thickness #I added this to change the thickness of the line on the plot
self.fig = fig
self.ax = ax
self.__ID1 = self.fig.canvas.mpl_connect('motion_notify_event', self.__motion_notify_callback)
self.__ID2 = self.fig.canvas.mpl_connect('button_press_event', self.__button_press_callback)
if sys.flags.interactive:
plt.show(block=False)
else:
plt.show()
def displayIAL(self, **linekwargs):
l = plt.Line2D(self.allxpoints,self.allypoints,color=self.roicolor,linewidth=self.thickness,**linekwargs)
values=(self.allxpoints,self.allypoints)
ax = plt.gca()
ax.add_line(l)
plt.draw()
return values
def __motion_notify_callback(self, event):
if event.inaxes:
ax = event.inaxes
x, y = event.xdata, event.ydata
if (event.button == None or event.button == 1) and self.line != None: # Move line around
self.line.set_data([self.previous_point[0], x],[self.previous_point[1], y])
self.fig.canvas.draw()
def __button_press_callback(self, event):
if event.inaxes:
x, y = event.xdata, event.ydata
ax = event.inaxes
if event.button == 1 and event.dblclick == False: # If you press the left button, single click
if self.line == None: # if there is no line, create a line
self.line = plt.Line2D([x, x],[y, y],marker='o',color=self.roicolor, linewidth=self.thickness)
self.start_point = [x,y]
self.previous_point = self.start_point
self.allxpoints=[x]
self.allypoints=[y]
ax.add_line(self.line)
self.fig.canvas.draw()
# add a segment
else: # if there is a line, create a segment
self.line = plt.Line2D([self.previous_point[0], x],[self.previous_point[1], y],marker = 'o',color=self.roicolor,linewidth=self.thickness)
self.previous_point = [x,y]
self.allxpoints.append(x)
self.allypoints.append(y)
event.inaxes.add_line(self.line)
self.fig.canvas.draw()
elif ((event.button == 1 and event.dblclick==True) or (event.button == 3 and event.dblclick==False)) and self.line != None: # close the loop and disconnect
self.fig.canvas.mpl_disconnect(self.__ID1) #joerg
self.fig.canvas.mpl_disconnect(self.__ID2) #joerg
self.line.set_data([self.previous_point[0],self.start_point[0]],[self.previous_point[1],self.start_point[1]])
ax.add_line(self.line)
self.fig.canvas.draw()
self.line = None
if sys.flags.interactive:
pass
else:
#figure has to be closed so that code can continue
plt.close(self.fig)
#This function returns a list of lists with the x coordinates and the y coordinates being separated into their own lists
def getIAL(img, width):
im = np.array(img)
plt.imshow(im, interpolation='nearest', cmap="Greys")
plt.title("left click: line segment, right click: close region")
ROIl = roipoly(roicolor='g',thickness=width)
plt.imshow(im, interpolation='nearest', cmap="Greys")
myIAL=ROIl.displayIAL()
plt.clf()
return myIAL
#This function takes the intensity of each x,y coordinate and then plots the intensities vs. distance along the line which was drawn
def IAL_Plot(IAL, image):
xvalues=IAL[0]
yvalues=IAL[1]
imarray=np.array(image)
intensityvalues=[]
for i in range(len(xvalues)):
x=int(xvalues[i])
y=int(yvalues[i])
intensityvalue=imarray[y,x]
intensityvalues.append(intensityvalue)
def display(Intensity):
plt.plot(Intensity)
plt.xlabel('Distance', fontsize=16)
plt.ylabel('Intensity',fontsize=16)
plt.show()
display(intensityvalues)
#Generate a greyscale plot
array=np.linspace(0,1,256*256)
mat=np.reshape(array,(256,256))
img=Image.fromarray(np.uint8(mat*255),'L')
myIAL=getIAL(img, 5) #get the coordinates of a line drawn on the image
plot=IAL_Plot(myIAL,img) #get the intensity at each coordinate point
我认为有一种pythonic方式可以做到这一点,或者至少是一种数学方式,但我到目前为止还是空白。任何帮助/建议将不胜感激。