在PGM格式文件中实现膨胀过滤器

2024-05-23 20:07:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在做一个学生项目,对灰度pgm文件进行一些图像处理(膨胀和腐蚀)。我试图在图像对象上实现膨胀,但得到了奇怪的结果。我预计图像对象将比原始图像大。但是根据我使用的内核大小,我得到了对象的多个副本

原图:

Original Picture

扩张结果:

Dilation Result

这是我的膨胀源代码

import numpy as np


def pgm_read(filename):
    """Read PGM file to a array"""
    # Performance Bottleneck: I/O system calls, parallel write/read
    try:
        with open(filename, 'r') as fp:
            lines = fp.readlines()
            header_info = lines[2].split()
            return np.array([line.strip('\n') for line in lines[4:]], dtype=np.int32).reshape(int(header_info[0]),
                                                                                              int(header_info[1]))
    except OSError:
        print("An exception occurred")


def pgm_write(img, dest, header):
    """Write numpy array to PGM file"""
    try:
        header = "P2\n# test\n" + header + "\n80\n"

        f = open(dest, "w")
        f.write(header)
        f.close()
        with open(dest, "a") as f:
            for x in range(img.shape[0]):
                for y in range(img.shape[1]):
                    f.write(str(img[x][y]) + "\n")
    except OSError:
        print("Writing exception occurred")


def dilation(img):

    rows, cols = img.shape
    dilated_img = np.zeros((rows, cols), dtype=np.int32)

    kernel = np.ones((2, 2))
    rows2, cols2 = kernel.shape

    for x in range(rows):
        for y in range(cols):
            """Search the object within the image"""
            if img[x][y] == 1:
                # Convolve with kernel
                for i in range(rows2):
                    for j in range(cols2):
                        if kernel[i][j] == 1:
                            # Object Enlargement
                            c = x + i
                            d = y + j
                            if c < rows and d < cols:
                                dilated_img[c][d] = 1

    for x in range(rows):
        for y in range(cols):
            """Give the object brightest colour for debugging purpose"""
            if dilated_img[x][y] == 1:
                dilated_img[x][y] = 80

    return dilated_img


if __name__ == '__main__':
    a = pgm_read("Axial_68.pgm")
    a = dilation(a)
    target = "Axial_68_1.pgm"
    header = "265 490"
    pgm_write(a, target, header)

Axial_68.pgm

我非常确定我的文件读取和写入功能工作正常,因为我可以使用它正确读取和写入其他源pgm文件

我发现有一件事很奇怪,我可以像这样打印半个pgm文件

Half Horizontal

使用代码

    for x in range(rows // 2):
        for y in range(columns):
            arr[x][y] = 80

但当我使用此代码并期望使用半垂直代码时:

    for x in range(rows):
        for y in range(columns // 2):
            arr[x][y] = 80

我明白了:

Half vertical

我用其他几个生成的pgm文件试过了,结果都是一样的。 我想知道我的膨胀码是否与这种奇怪的行为有关


Tags: 文件inimgforifnprangekernel
1条回答
网友
1楼 · 发布于 2024-05-23 20:07:27

它总是有助于直接显示矩阵,而不是依赖于您自己编写的例程将其写入文件进行检查。例如,添加

import matplotlib.pyplot as pp
#...
    a = pgm_read("Axial_68.pgm")
    pp.imshow(a)
    pp.show()

对代码的修改会立即显示输入图像未正确读入。在reshape函数调用中交换两个维度为我修复了它:

return np.array([line.strip('\n') for line in lines[4:]], dtype=np.int32).reshape(int(header_info[1]),
                                                                                  int(header_info[0]))

我强烈建议您使用库来读写图像文件。例如imageio是一个很好的选择。Matplotlib本身也可以读取和写入各种图像文件格式。 如果你想做图像处理,也要为它准备一个库。例如PillowOpenCVDIPlib。这些还包括图像文件读取和写入功能

相关问题 更多 >