我有以下图像:
下面是该图像内的分割蒙版:
根据上图,我试图计算非零像素坐标。也就是说,我尝试获取上面遮罩中的实际云的所有像素。当我绘制这些非零像素时,结果是这样的:
我的问题是:为什么上面图像中绘制的像素与分割蒙版中的像素不同,我该如何解决?我想从分割蒙版中获取云的像素。
代码:
# 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()
答案 0 :(得分:1)
您可能正在寻找matplotlib.pyplot.scatter()
似乎与阈值图像匹配
import cv2
from matplotlib import pyplot as plt
import numpy as np
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 110, 255, cv2.THRESH_BINARY)[1]
x, y = np.where(thresh > 0)
plt.scatter(y[::-1], x)
plt.title('Plot segmentation mask pixels')
plt.show()
答案 1 :(得分:1)
添加@nathancy的答案并明确回答这个问题:从分割蒙版计算出的像素确实是。上面最后一个图中出现锯齿形状的原因是因为来自蒙版的每个坐标都绘制为单个(闭合)多边形,并且所有这些点都已连接。那就是多边形的定义:
因此,最终图表示一个封闭的多边形,其中包含原始分割蒙版中的每个像素/坐标。
要生成精确的多边形,您需要从蒙版中找到(任何可能的)轮廓的顶点。示例:
# 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()
结果: