Python,有没有办法在较大图像区域内找到子区域的属性?

问题描述

目标:我的图像带有需要查找其区域的粒子。 ((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]
     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

解决方法

我对这个问题尚不完全清楚,但如果我正确理解以下内容,则应该起作用:

  1. 标记大颗粒灰度图像(skimage.morphology.label)中的颗粒
  2. 使用子区域蒙版之一屏蔽图像(您可以为此使用numpy索引,例如label_image[mask]
  3. 查看剩下的标签,这些标签标识与蒙版(np.unique(label_image[mask]))重叠的粒子
  4. 重复其余子区域

您可以测量np.unique(label_image,return_counts=True)之类的区域。这将返回标签数组和具有该标签的像素数数组。同样,对于仅由mask定义的给定子区域中的像素,您可以测量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,0],[ 255,[   0,255],255]],dtype='uint8')

subregion_image = np.array(
    [[255,[255,[  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[:,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)

由于您将遍历子区域,因此如果您有数百万个子区域,则此方法可能不会很快。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...