numpy 如果一张图像中有多个ROI,如何计算每个ROI的RGB平均值?

gopyfrb3  于 2023-11-18  发布在  其他
关注(0)|答案(1)|浏览(148)

我有一个RGB格式的3通道图像,包含许多建筑物作为感兴趣的区域。图像的背景是完全黑色的(零像素)。我试图计算每个ROI的颜色特征,并将其保存在CSV文件中,但我的代码只取单个RGB值作为每个通道的平均值,因为我需要保存R,G,B,CSV文件中每个ROI的RGB和RGB平均值。如有任何指导,将不胜感激。enter image description here

import numpy as np
import pandas as pd
from skimage import io

image = io.imread("/content/drive/MyDrive/277.png")

current_roi = 1
start_pixel = None
roi_mean_values = []

for y in range(image.shape[0]):
for x in range(image.shape[1]):

pixel_value = image[y, x]

     if np.any(pixel_value > 0):  
           if start_pixel is None:
                 start_pixel = (x, y)
           elif start_pixel is not None:
               end_pixel = (x - 1, y)  # End of the current ROI
               roi = image[start_pixel[1]:end_pixel[1] + 1, start_pixel[0]:end_pixel[0] + 1]
    
               mean_rgb = np.mean(roi, axis=(0, 1))
               roi_mean_values.append({'ROI': current_roi,
                                    'Mean_R': mean_rgb[0],
                                    'Mean_G': mean_rgb[1],
                                    'Mean_B': mean_rgb[2]})
    
              current_roi += 1
              start_pixel = None

roi_mean_df = pd.DataFrame(roi_mean_values)

roi_mean_df.to_csv("roi_mean_values.csv", index=False)

print("RGB mean values for individual buildings (ROIs) saved to 'roi_mean_values.csv'.")

字符串

col17t5w

col17t5w1#

据我所知,ROI由输入图像的connected components给出。每个连接的组件都是一个ROI。
你可以在不迭代ROI的情况下解决这个问题,如果有很多ROI的话,这会变得非常昂贵。但是,这段代码确实显式地遍历了像素,这在Python中很慢。也许,迭代ROI并使用编译函数来处理所有像素会产生更快的Python代码,即使实际上要做更多的工作。但是用编译语言编写,这个算法是你能写的最有效的算法。

import numpy as np
import skimage

image = skimage.io.imread("/Users/cris/Downloads/G4IXb.png")
n_channels = image.shape[2]

# Find binary image separating background and objects
mask = np.any(image > 0, axis=2)

# Label this mask image, each ROI gets a unique label
lab, n_labs = skimage.measure.label(mask, return_num=True)

# Create arrays where we'll collect the information
sum = np.zeros((n_labs + 1, n_channels))
number = np.zeros(n_labs + 1)

# Loop over all pixels.
for ii in range(image.shape[0]):
    for jj in range(image.shape[1]):
        # For each pixel, look at the label, and add information to
        # the arrays for that label.
        index = lab[ii, jj]
        sum[index, :] += image[ii, jj, :]
        number[index] += 1

# We're done. The mean color is the sum divided by the number of pixels.
mean_colors = sum / number[:, None]

字符串
让我们看看平均颜色是什么样子的:

# Paint an image with the mean colors
mean_colors = np.round(mean_colors).astype(np.uint8)
out = np.empty_like(image)
for ii in range(image.shape[0]):
    for jj in range(image.shape[1]):
        out[ii, jj] = mean_colors[lab[ii, jj]]

import matplotlib.pyplot as plt
plt.subplot(1, 2, 1)
plt.imshow(image)
plt.subplot(1, 2, 2)
plt.imshow(out)
plt.show()


的数据
当然,由于我们使用skimage,我们也可以使用skimage.measure.regionprops,并获得intensity_mean属性:

props = skimage.measure.regionprops(lab, image)
cols = np.zeros((n_labs + 1, n_channels))
for p in props:
    cols[p.label, :] = p.intensity_mean

相关问题