Python,有没有办法在更大的图像区域内找到子区域的属性?
Python, Is there a way to find the properties of a subregion within a larger image region?
目标:我有带粒子的图像,我需要找到它们的面积。 ((array([], dtype=int32), array([], dtype=int64)), <class 'numpy.ndarray'> (512, 512, 3) <class 'tuple'>
)每个粒子还有四到五个子区域,我需要知道它们的面积。想一想图片中的一堆脱衣衬衫。我需要找到每件衬衫的面积,对于某件衬衫,我需要知道每条条纹的面积。问题是我需要知道条纹对应哪件衬衫。我需要知道较小区域对应的粒子。这样我就可以获得一个区域中每个子区域的百分比面积。
我有一个灰度大颗粒的图像,一个所有覆盖子区域的图像和每个子区域的图像。我创建了一个简化的图像模型。 [SubRegion1][1] [SubRegion2][2] [TotalAreaRegion][3]
我尝试过的:
使用 openCV 进行分割,然后使用 scikit-image.org 中的 regionprops 我可以获得主要粒子大小、纵横比等。
我不能做的是获得这些子区域区域并知道它们去哪个父粒子。当我需要一个时,我会生成两个单独的标签列表。
代码:
#markers are the marked regions in the total image. red_markers are the marked sub-regions in the second image.
markers = cv2.watershed(crop_img, markers)
red_markers = cv2.watershed(red_crop_img, red_markers)
#if marker = 1, bg, then color
crop_img[markers == 1] = [0, 255, 255]
red_crop_img[red_markers == 1] = [0, 255, 255]
img2 = color.label2rgb(markers, bg_label=0)
red_img2 = color.label2rgb(red_markers, bg_label=0)
mask = red_markers == 255
masked_img = markers[mask] = 255
img3 = np.unique(masked_img, return_counts=True)
print(img3)
output: array[0]array[255]
'''
[1]: https://i.stack.imgur.com/wVef6.png
[2]: https://i.stack.imgur.com/AhqDZ.png
[3]: https://i.stack.imgur.com/cZWJC.png
我不是很清楚这个问题,但如果我理解正确,下面的方法应该可行:
- 在大粒子灰度图中标注粒子(
skimage.morphology.label
)
- 使用 sub-region 遮罩之一遮罩图像(您可以为此使用 numpy 索引,例如
label_image[mask]
)
- 查看保留了哪些标签,这些标签标识了与遮罩重叠的粒子 (
np.unique(label_image[mask])
)
- 对剩余的 sub-regions
重复
您可以测量 np.unique(label_image, return_counts=True)
等区域。这将 return 一个标签数组和一个包含该标签的像素数的数组。同样,对于掩码定义的给定 sub-region 中的像素,您可以测量像 np.unique(label_image[mask], return_counts=True)
.
这样的区域
这是一个演示这种方法的 MWE
import numpy as np
import skimage.morphology
### Create example images
full_image = np.array(
[[ 255, 255, 255, 0, 0],
[ 255, 255, 255, 0, 0],
[ 0, 0, 0, 0, 0],
[ 0, 0, 0, 255, 255],
[ 255, 255, 0, 255, 255]],
dtype='uint8')
subregion_image = np.array(
[[255, 0, 255, 0, 0],
[255, 0, 255, 0, 0],
[ 0, 0, 0, 0, 0],
[ 0, 0, 0, 255, 255],
[ 0, 0, 0, 0, 0]],
dtype='uint8')
# Make format match that format (i.e. RGB) and datatype of OP
full_image = np.repeat(full_image[:, :, np.newaxis], 3, axis=2).astype(dtype='int32')
subregion_image = np.repeat(subregion_image[:, :, np.newaxis], 3, axis=2).astype(dtype='int64')
### Simplify images
# If we know all three channels are the same it's easier (and equivalent) to have a single channel
full_image = full_image[:, :, 0]
subregion_image = subregion_image[:, :, 0]
# If we know values are all in the range 0 to 255 we may as well use uint8, miage not matter but it's
# generally helps avoid confusion when dealing with images to have intensity range and datatype match
full_image = full_image.astype('uint8')
subregion_image = subregion_image.astype('uint8')
### Solve the problem
# Label the particles in the large particle image
label_image = skimage.morphology.label(full_image)
# Create a mask for the sub-region
mask = subregion_image == 255
# See which labels remain, these labels identify the particles that overlap with the mask
print(np.unique(label_image[mask]))
# To measure the area we'll set pixels outside the subregion to 0 for background
label_image[~mask] = 0
# Count pixels belonging to each particle
particle_label, pixel_count = np.unique(label_image, return_counts=True)
print(particle_label)
print(pixel_count)
如果您有 PIL 图像或类似图像,您可能需要转换为 numpy 数组,例如 your_image = np.array(your_image)
。
由于您将遍历 sub-regions,如果您有数百万个 sub-regions,这种方法可能不会特别快。
目标:我有带粒子的图像,我需要找到它们的面积。 ((array([], dtype=int32), array([], dtype=int64)), <class 'numpy.ndarray'> (512, 512, 3) <class 'tuple'>
)每个粒子还有四到五个子区域,我需要知道它们的面积。想一想图片中的一堆脱衣衬衫。我需要找到每件衬衫的面积,对于某件衬衫,我需要知道每条条纹的面积。问题是我需要知道条纹对应哪件衬衫。我需要知道较小区域对应的粒子。这样我就可以获得一个区域中每个子区域的百分比面积。
我有一个灰度大颗粒的图像,一个所有覆盖子区域的图像和每个子区域的图像。我创建了一个简化的图像模型。 [SubRegion1][1] [SubRegion2][2] [TotalAreaRegion][3]
我尝试过的: 使用 openCV 进行分割,然后使用 scikit-image.org 中的 regionprops 我可以获得主要粒子大小、纵横比等。 我不能做的是获得这些子区域区域并知道它们去哪个父粒子。当我需要一个时,我会生成两个单独的标签列表。
代码:
#markers are the marked regions in the total image. red_markers are the marked sub-regions in the second image.
markers = cv2.watershed(crop_img, markers)
red_markers = cv2.watershed(red_crop_img, red_markers)
#if marker = 1, bg, then color
crop_img[markers == 1] = [0, 255, 255]
red_crop_img[red_markers == 1] = [0, 255, 255]
img2 = color.label2rgb(markers, bg_label=0)
red_img2 = color.label2rgb(red_markers, bg_label=0)
mask = red_markers == 255
masked_img = markers[mask] = 255
img3 = np.unique(masked_img, return_counts=True)
print(img3)
output: array[0]array[255]
'''
[1]: https://i.stack.imgur.com/wVef6.png
[2]: https://i.stack.imgur.com/AhqDZ.png
[3]: https://i.stack.imgur.com/cZWJC.png
我不是很清楚这个问题,但如果我理解正确,下面的方法应该可行:
- 在大粒子灰度图中标注粒子(
skimage.morphology.label
) - 使用 sub-region 遮罩之一遮罩图像(您可以为此使用 numpy 索引,例如
label_image[mask]
) - 查看保留了哪些标签,这些标签标识了与遮罩重叠的粒子 (
np.unique(label_image[mask])
) - 对剩余的 sub-regions 重复
您可以测量 np.unique(label_image, return_counts=True)
等区域。这将 return 一个标签数组和一个包含该标签的像素数的数组。同样,对于掩码定义的给定 sub-region 中的像素,您可以测量像 np.unique(label_image[mask], return_counts=True)
.
这是一个演示这种方法的 MWE
import numpy as np
import skimage.morphology
### Create example images
full_image = np.array(
[[ 255, 255, 255, 0, 0],
[ 255, 255, 255, 0, 0],
[ 0, 0, 0, 0, 0],
[ 0, 0, 0, 255, 255],
[ 255, 255, 0, 255, 255]],
dtype='uint8')
subregion_image = np.array(
[[255, 0, 255, 0, 0],
[255, 0, 255, 0, 0],
[ 0, 0, 0, 0, 0],
[ 0, 0, 0, 255, 255],
[ 0, 0, 0, 0, 0]],
dtype='uint8')
# Make format match that format (i.e. RGB) and datatype of OP
full_image = np.repeat(full_image[:, :, np.newaxis], 3, axis=2).astype(dtype='int32')
subregion_image = np.repeat(subregion_image[:, :, np.newaxis], 3, axis=2).astype(dtype='int64')
### Simplify images
# If we know all three channels are the same it's easier (and equivalent) to have a single channel
full_image = full_image[:, :, 0]
subregion_image = subregion_image[:, :, 0]
# If we know values are all in the range 0 to 255 we may as well use uint8, miage not matter but it's
# generally helps avoid confusion when dealing with images to have intensity range and datatype match
full_image = full_image.astype('uint8')
subregion_image = subregion_image.astype('uint8')
### Solve the problem
# Label the particles in the large particle image
label_image = skimage.morphology.label(full_image)
# Create a mask for the sub-region
mask = subregion_image == 255
# See which labels remain, these labels identify the particles that overlap with the mask
print(np.unique(label_image[mask]))
# To measure the area we'll set pixels outside the subregion to 0 for background
label_image[~mask] = 0
# Count pixels belonging to each particle
particle_label, pixel_count = np.unique(label_image, return_counts=True)
print(particle_label)
print(pixel_count)
如果您有 PIL 图像或类似图像,您可能需要转换为 numpy 数组,例如 your_image = np.array(your_image)
。
由于您将遍历 sub-regions,如果您有数百万个 sub-regions,这种方法可能不会特别快。