from skimage.segmentation import slic, mark_boundaries import torchvision.transforms as transforms import numpy as np from PIL import Image import matplotlib.pyplot as plt import cv2 # 加载图像 image = Image.open('img.png') # 转换为 PyTorch 张量 transform = transforms.ToTensor() img_tensor = transform(image).unsqueeze(0) # 将 PyTorch 张量转换为 Numpy 数组 img_np = img_tensor.numpy().transpose(0, 2, 3, 1)[0] # 使用 SLIC 算法生成超像素标记图 segments = slic(img_np, n_segments=100, compactness=10) # 可视化超像素标记图 segment_img = mark_boundaries(img_np, segments) # 将 Numpy 数组转换为 PIL 图像 segment_img = Image.fromarray((segment_img * 255).astype(np.uint8)) # 保存超像素标记图 segment_img.save('segments.jpg') n_segments = np.max(segments) + 1 # 初始化超像素块的区域 segment_regions = np.zeros((n_segments, img_np.shape[0], img_np.shape[1])) # 遍历每个超像素块 for i in range(n_segments): # 获取当前超像素块的掩码 mask = (segments == i) # 将当前超像素块的掩码赋值给超像素块的区域 segment_regions[i][mask] = 1 # 保存超像素块的区域 np.save('segment_regions.npy', segment_regions) # 加载超像素块的区域 segment_regions = np.load('segment_regions.npy') # 取出第一个超像素块的区域 segment_region = segment_regions[37] segment_region = (segment_region * 255).astype(np.uint8) # 显示超像素块的区域 plt.imshow(segment_region, cmap='gray') plt.show() # 初始化空白图像 output = np.zeros_like(img_np) # 遍历每个超像素块 for i in range(n_segments): # 获取当前超像素块的掩码 mask = segments == i # 将当前超像素块的掩码赋值给输出图像 output[mask] = segment_regions[i] * 255 # 绘制超像素块的边缘 contours, _ = cv2.findContours(mask.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(output, contours, -1, (255, 255, 0), 1) # 显示超像素块的区域和边缘 plt.imshow(output) plt.show()上述代码出现问题:ValueError: shape mismatch: value array of shape (500,500) could not be broadcast to indexing result of shape (0,3)
时间: 2024-03-08 21:48:02 浏览: 78
这个错误是由于 `cv2.findContours` 函数没有找到任何轮廓导致的。在这种情况下,返回的轮廓列表为空,因此不能用它来绘制轮廓。为了避免出现这个错误,你可以在调用 `cv2.findContours` 函数前,先判断当前超像素块的掩码中是否存在非零值,如果不存在,则跳过绘制轮廓的步骤。
下面是修改后的代码:
```python
import cv2
# 初始化空白图像
output = np.zeros_like(img_np)
# 遍历每个超像素块
for i in range(n_segments):
# 获取当前超像素块的掩码
mask = segments == i
# 将当前超像素块的掩码赋值给输出图像
output[mask] = segment_regions[i] * 255
# 判断当前超像素块的掩码中是否存在非零值
if np.count_nonzero(mask) > 0:
# 绘制超像素块的边缘
contours, _ = cv2.findContours(mask.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(output, contours, -1, (255, 255, 0), 1)
# 显示超像素块的区域和边缘
plt.imshow(output)
plt.show()
```
上述代码中,我们使用 `np.count_nonzero` 函数来判断当前超像素块的掩码中是否存在非零值。如果存在,则调用 `cv2.findContours` 函数来绘制轮廓。否则,跳过绘制轮廓的步骤。这样就可以避免上述错误的出现了。
阅读全文