【问题标题】:Divide Binary Image to 4x4 Python and Counting the Pixels将二进制图像划分为 4x4 Python 并计算像素
【发布时间】:2018-10-30 17:47:33
【问题描述】:

我有一个二进制图像,我想将它分成 4 x 4 像素的块并计算块中黑色像素的数量。如果一个块中黑色像素的总和为偶数,则对应的块被赋值为0。否则,值为1。然后,将其保存/写入txt文件以便我可以看到结果。

我尝试过使用代码但卡住了

import matplotlib.pyplot as plt
import numpy as np
image = plt.imread('myplot1.png')
image = np.array(image)
image = image[:,:,1] #if RGB

print(image.shape)
for x in np.arange(0,image.shape[0]):
    for y in np.arange(image.shape[1]):
        if x+4 < image.shape[0] and y+4 < image.shape[1]:
             sum = np.sum(image[x:x+4,y:y+4])
             if sum > 4:
                image[x:x + 4, y:y + 4] = 1
             elif sum < 4:
                image[x:x + 4, y:y + 4] = 0

【问题讨论】:

  • "4x4 Python"?) 已锁定、已加载并准备就绪 :)

标签: python image opencv image-processing python-imaging-library


【解决方案1】:

the solution provided to this question 的帮助下将二维数组拆分为更小的块:

def block_view(A, block):
    # Reshape the array into a 2D array of 2D blocks, with the resulting axes in the
    # order of:
    #    block row number, pixel row number, block column number, pixel column number
    # And then rearrange the axes so that they are in the order:
    #    block row number, block column number, pixel row number, pixel column number
    return A.reshape(A.shape[0]//block[0], block[0], A.shape[1]//block[1], block[1])\
            .transpose(0, 2, 1, 3)

# Initial grayscale image
image = np.random.rand(16, 16)

# Boolean array where value is True if corresponding pixel in `image` is
# "black" (intensity less than 0.5)
image_bin = image < 0.5

# Create a 2D array view of 4x4 blocks
a = block_view(image_bin, (4, 4))

# XOR reduce each 4x4 block (i.e. reduce over last two axis), so even number
# of blacks is 0, else 1
a = np.bitwise_xor.reduce(a, axis=(-2, -1))

print(a.astype(np.uint8))

16x16 图像的示例输出:

[[0 1 1 0]
 [0 0 1 0]
 [1 1 1 1]
 [0 0 0 1]]

编辑:

block_view() 函数最初是在this answer(使用as_strided())之后实现的,但是经过更多搜索后,我决定改用this answer 的变体(它利用了整形)。对这两种方法进行计时,后者大约快 8 倍(至少通过我的测试)。

【讨论】:

  • 谢谢,对我帮助很大! :)
  • @DianAriefRisdianto 哦不,我犯了一个大错误,np.reshape(image_bin, (-1, 4*4))不是将数组重新整形为可索引的 4x4 块的正确方法,这是一种简单的查看方法这个试试print(np.reshape(range(32), (-1, 4*4)))。它所要做的就是收集 16 个连续的元素,而不是 4x4 块中的元素。我已经更新了这个问题来解决这个问题,非常感谢an answer to another question。抱歉,在将其作为答案提交之前,我应该在测试解决方案时更加谨慎。
  • @eugenhu 这个错误是一个很好的例子,为什么 einops 如此有用
【解决方案2】:

Einops 允许详细减少。你的情况

import numpy as np
from einops import reduce

# Black / white image
image = np.random.rand(16, 16) < 0.5

# compute number of bright pixels in each block, then compute residual modulo 2
reduce(image, '(h h2) (w w2) -> h w', 'sum', h2=4, w2=4) % 2

示例输出:

array([[0, 0, 1, 1],
       [1, 1, 0, 1],
       [1, 0, 1, 1],
       [0, 0, 1, 1]])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 2015-06-04
    • 1970-01-01
    • 2013-12-19
    • 1970-01-01
    • 2015-08-02
    • 2013-02-15
    相关资源
    最近更新 更多