I'm fairly new to Python and am stuck on a problem...
I'm trying to draw a region of interest (ROI) on an image and calculate the average pixel value in that ROI.
To start, I tried the following - first I used matplotlib.widgets.PolygonSelector
to draw a polygon, and then used path.contains_points to create
a mask that I could then apply to the original image.
class ROIPolygon(object):
def __init__(self, ax, row, col):
self.canvas = ax.figure.canvas
self.poly = PolygonSelector(ax,
self.onselect,
lineprops = dict(color = 'g', alpha = 1),
markerprops = dict(mec = 'g', mfc = 'g', alpha = 1))
self.path = None
def onselect(self, verts):
path = Path(verts)
self.canvas.draw_idle()
self.path = path
def get_mask(drawn_roi, row, col):
for i in np.arange(row):
for j in np.arange(col):
if drawn_roi.path.contains_points([(j,i)]) == [True]:
mask[i][j] = 1
mask_bool = mask.astype(bool)
mask_bool = ~mask_bool
return mask_bool
But when I tested this out on a small image containing only 4 colored pixels, I get this image before drawing ROI:
And this one after drawing ROI:
I expected the mask array to return only 4 False values.
[[ True True True True True True True True True True]
[ True True True True True True True True True True]
[ True True True True True True True True True True]
[ True True True True True True True True True True]
[ True True True True True False False True True True]
[ True True True True True False False True True True]
[ True True True True True True True True True True]
[ True True True True True True True True True True]
[ True True True True True True True True True True]
[ True True True True True True True True True True]]
But instead it returned 12 False values. As well, if I were to draw the ROI even larger, I would return more False values.
[[ True True True True True True True True True True]
[ True True True True True True True True True True]
[ True True True True True True True True True True]
[ True True True True True True True True True True]
[ True True True True False False False False True True]
[ True True True True False False False False True True]
[ True True True True False False False False True True]
[ True True True True True True True True True True]
[ True True True True True True True True True True]
[ True True True True True True True True True True]]
So I am wondering if there is something wrong with my approach, or if there is a particular interaction between the PolygonSelector
and path.contains_points I am missing?
Thanks!
For anyone else that got confused as I was (by not reading documentation clearly), I solved my problem by altering my get_mask function as follows:
def get_mask(img_frame, drawn_roi, row, col):
for i in np.arange(row):
for j in np.arange(col):
if np.logical_and(drawn_roi.path.contains_points([(j,i)]) == [True], img_frame[i][j] > 0):
mask[i][j] = 1
mask_bool = mask.astype(bool)
mask_bool = ~mask_bool
return mask_bool