【问题标题】:create a grid on 2D array and count values在二维数组上创建一个网格并计算值
【发布时间】:2021-08-01 00:58:02
【问题描述】:

大家好,

我正在处理天文拟合图像。从 fit 文件中,我得到了这个 2D 图像/2D numpy 数组。

我的目标是首先创建一个网格(例如我在上面手动绘制的),然后从该网格的每个单元格中计算其中的值。框的大小必须固定为 25x25 像素。

我不知道什么是最好的方法。我想知道是否有办法使用pyregiongeopandas(我不太熟悉)。欢迎任何建议或示例!

使用pyregion,我可以绘制一个特定的,比方说,平方区域,然后一次计算其中的计数......但完美的是一次完成所有操作,而不是创建一个每个单元格中的计数图。

【问题讨论】:

  • 如果您有numpy.array,则只需使用for-loop 将像素替换为绿色 - 它不需要任何其他模块来绘制它。最终,您可以使用pillowopenCV 在图像上绘图。你必须在某个单元格中计算然后简单地得到这个区域arr[y1:y2, x1:x2]

标签: python arrays image grid


【解决方案1】:

如果您有numpy.array,那么您可以使用cv2.rectangle 来绘制网格。

img_grid = cv2.rectangle(img_grid, (x, y, BOX_W+1, BOX_H+1), GREEN)

您可以在for-loop 中进行操作。

for y in range(0, height, BOX_H):
    for x in range(0, width, BOX_W):
        img_grid = cv2.rectangle(img_grid, (x, y, BOX_W+1, BOX_H+1), GREEN)

我也使用cv2 来加载图像和保存图像。

import cv2

GREEN = (0, 255, 0)  # BGR instead of RGB
BOX_W = 25
BOX_H = 25

img = cv2.imread('lenna.png')
height, width = img.shape[:2]

img_grid = img.copy()  # to keep original image for calculations

for y in range(0, height, BOX_H):
    for x in range(0, width, BOX_W):
        img_grid = cv2.rectangle(img_grid, (x, y, BOX_W+1, BOX_H+1), GREEN)

cv2.imshow('image', img_grid)
cv2.waitKey(0)

cv2.imwrite('lenna_grid.png', img_grid)

cv2.destroyAllWindows()

图片Lenna来自维基百科:


您可以使用for-loop 获取框中的值并进行计算的相同方式。

for y in range(0, height, BOX_H):
    for x in range(0, width, BOX_W):
        x1 = x
        y1 = y
        x2 = x + BOX_W
        y2 = y + BOX_H

        data = img[y1:y2, x1:x2]

        result = data.mean()

        print(f'mean for [{y1:3}:{y2:3}, {x1:3}:{x2:3}]: {result:6.2f}')

结果:

mean for [  0: 25,   0: 25]: 155.60
mean for [  0: 25,  25: 50]: 159.80
mean for [  0: 25,  50: 75]: 125.37
mean for [  0: 25,  75:100]: 110.78
mean for [  0: 25, 100:125]: 121.00
mean for [  0: 25, 125:150]: 132.41
mean for [  0: 25, 150:175]: 134.54
mean for [  0: 25, 175:200]: 135.22
mean for [  0: 25, 200:225]: 134.36
mean for [  0: 25, 225:250]: 134.32
mean for [  0: 25, 250:275]: 133.63
mean for [  0: 25, 275:300]: 131.61

完整代码:

import cv2

GREEN = (0, 255, 0)  # BGR instead of RGB
BOX_W = 25
BOX_H = 25

img = cv2.imread('lenna.png')   # `img` is a `numpy array` (but in BGR instead of RGB)
height, width = img.shape[:2]

img_grid = img.copy()  # to keep original image for calculations

for y in range(0, height, BOX_H):
    for x in range(0, width, BOX_W):
        img_grid = cv2.rectangle(img_grid, (x, y, BOX_W+1, BOX_H+1), GREEN)

cv2.imshow('image', img_grid)
cv2.waitKey(0)  # press any key to close window

cv2.imwrite('lenna_grid.png', img_grid)

cv2.destroyAllWindows()

# -----------------------------------------

for y in range(0, height, BOX_H):
    for x in range(0, width, BOX_W):
        x1 = x
        y1 = y
        x2 = x + BOX_W
        y2 = y + BOX_H
        data = img[y1:y2, x1:x2]
        result = data.mean()
        print(f'mean for [{y1:3}:{y2:3}, {x1:3}:{x2:3}]: {result:6.2f}')

编辑:

您也可以在没有cv2.rectangle 的情况下绘制矩形 - 您可以替换数组中的像素

    # left line   
    img_grid[y1:y2, x1] = GREEN

    # right line
    img_grid[y1:y2, x2] = GREEN

    # top line
    img_grid[y1, x1:x2] = GREEN

    # bottom line
    img_grid[y2, x1:x2] = GREEN

但它可能需要检查x2y2 是否仍在图像内。

    if x2 >= width:
        x2 = width-1
    if y2 >= height:
        y2 = height-1

#import numpy as np
import cv2

GREEN = (0, 255, 0)  # BGR instead of RGB
BOX_W = 25
BOX_H = 25

img = cv2.imread('lenna.png')
height, width = img.shape[:2]

img_grid = img.copy()  # to keep original image for calculations

for y in range(0, width, BOX_H):
    for x in range(0, height, BOX_W):

        x1 = x
        y1 = y
        x2 = x + BOX_W
        y2 = y + BOX_H
        
        if x2 >= width:
            x2 = width-1
        if y2 >= height:
            y2 = height-1
            
        # left line   
        img_grid[y1:y2, x1] = GREEN
        
        # right line
        img_grid[y1:y2, x2] = GREEN
        
        # top line
        img_grid[y1, x1:x2] = GREEN
        
        # bottom line
        img_grid[y2, x1:x2] = GREEN

cv2.imshow('image', img_grid)
cv2.waitKey(0)

cv2.imwrite('lenna_grid.png', img_grid)

cv2.destroyAllWindows()

顺便说一句: cv2 也可以使用窗口来选择一些区域(ROI)

您绘制矩形并按SPACE 接受。在最后一个矩形后按ESC 使用区域。

#import numpy as np
import cv2

GREEN = (0, 255, 0)  # BGR instead of RGB
BOX_W = 25
BOX_H = 25

img = cv2.imread('/home/furas/test/lenna.png')
height, width = img.shape[:2]

regions = cv2.selectROIs('Image', img)
print(regions)

for number, (x, y, w, h) in enumerate(regions, 1):
    x1 = x
    y1 = y
    x2 = x + BOX_W
    y2 = y + BOX_H
    data = img[y1:y2, x1:x2]
    result = data.mean()
    
    print(f'mean for [{y1:3}:{y2:3}, {x1:3}:{x2:3}]: {result:6.2f}')
            
    cv2.imshow(f"Crop {number}", data)
    
cv2.waitKey(0)

cv2.destroyAllWindows()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    • 2017-12-07
    • 1970-01-01
    • 2013-07-16
    相关资源
    最近更新 更多