计算并绘制分割蒙版像素 [英] Calculate and plot segmentation mask pixels

查看:113
本文介绍了计算并绘制分割蒙版像素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下图像:

下面是该图像内的分割蒙版:

Below is a segmentation mask within this image:

根据上图,我试图计算非零像素坐标.也就是说,我试图获取上面遮罩中的实际云的所有像素.当我绘制这些非零像素时,结果是这样的:

From the image above, I attempted to calculate the non-zero pixel coordinates. That is, I tried to get all of the pixels of the actual clouds that are in the mask above. When I plot these non-zero pixels, the results are this:

我的问题是:为什么上面图像中绘制的像素与分割蒙版中的像素不同,我该如何解决?我想从分割蒙版中获取云的像素.

My question is: why are the plotted pixels in the image above not the same as from the segmentation mask, and how do I fix this? I want to get the pixels of the clouds from the segmentation mask.

代码:

# create matrix
canvas = np.zeros((img_h, img_w))

# read in image, convert to grayscale, and create mask
im_color = cv2.imread(first_row.path.values[0], cv2.COLOR_BGR2RGB)
im_gray = cv2.cvtColor(im_color, cv2.COLOR_BGR2GRAY)
_, mask = cv2.threshold(im_gray, thresh=110, maxval=255, type=cv2.THRESH_BINARY)

# bounding box coordinates for segmentation mask
ymin, ymax, xmin, xmax = 2, 222, 42, 521

# assign mask to coordinates on canvas
canvas[ymin:ymax,xmin:xmax] = mask[ymin:ymax,xmin:xmax]
y_coords, x_coords = np.where(canvas == 255.0)

# get pixel coordinates of nonzero pixels
pts = np.array(list(zip(x_coords, y_coords)))

# plot original image 
fig1 = plt.figure()
ax1 = fig1.add_axes([0,0,1,1])
ax1.set_title('Original image')
plt.imshow(im_color)

# plot segmentation mask on canvas
fig2 = plt.figure()
ax2 = fig2.add_axes([0,0,1,1])
ax2.set_title('Segmentation mask on canvas')
plt.imshow(canvas)

# plot segmentation mask pixels
fig3 = plt.figure()
ax3 = fig3.add_axes([0,0,1,1])
ax3.set_title('Segmentation mask pixel coordinates')
plt.imshow(im_color, interpolation='none')
poly = patches.Polygon(pts)
ax3.add_patch(poly)
plt.show()

推荐答案

要添加@nathancy的答案并明确回答以下问题:从分割蒙版计算出的像素确实准确.上面最后一个图中出现锯齿状的原因是因为蒙版中的每个坐标都绘制为单个(闭合)多边形,并且所有这些点都已连接.那就是多边形的定义:

To add upon @nathancy's answer and explicitly answer the question: the pixels calculated from the segmentation mask are indeed accurate. The reason for the jagged shape in the last plot above is because every coordinate from the mask is plotted as a single (closed) polygon, and all of these points are connected. That is the definition of a polygon:

  • 许多共面的线段,每个线段首尾相连以形成闭合形状."

因此,最终图表示一个封闭的多边形,其中包含原始分割蒙版中的每个像素/坐标.

So the final plot represents a closed polygon containing every pixel/coordinate from the original segmentation mask.

要生成准确的多边形,您需要从蒙版中找到(任何可能的)轮廓的顶点.示例:

To produce an accurate polygonal shape, you would need to find the vertices of (any possible) contours from the mask. Example:


# set up canvas for mask
mask = np.zeros((img_h, img_w), dtype=np.uint8)

# assign specific region to mask
mask[ymin:ymax,xmin:xmax] = 1

# read in image
im_color = cv2.imread(path, cv2.IMREAD_COLOR)

# convert image to grayscale
im_gray = cv2.cvtColor(im_color, cv2.COLOR_BGR2GRAY)

# create threshold of image
_, thresh = cv2.threshold(im_gray, thresh=100, maxval=255, type=cv2.THRESH_BINARY)

# create segmentation mask of thresholded image
masked_gray = cv2.bitwise_and(thresh, thresh, mask = mask)

# calculate contours of segmentation mask
contours, hierarchy = cv2.findContours(masked_gray, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# get largest contour
tc = max(contours, key=len)

# plot contours
fig = plt.figure()
ax = fig.add_axes([0,0,1,1])
ax.set_title('Segmentation mask')
plt.imshow(masked_gray, interpolation='none')
poly = patches.Polygon(tc[:,0])
ax.add_patch(poly)
plt.show()

结果:

这篇关于计算并绘制分割蒙版像素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆