【问题标题】:Normalization of grayscale fingerprint images灰度指纹图像的归一化
【发布时间】:2023-03-05 07:32:02
【问题描述】:

我正在尝试按照第 2.3 节中的this paper 中的建议对灰度指纹图像进行标准化。为了测试它,我使用了这个gray fingerprint,标准化后我希望它看起来像这样normalized fingerprint

这是我用来标准化指纹的函数

import numpy as np
from glob import glob
from PIL import Image
import matplotlib.pyplot as plt


def normalization(im_arr, M0, VAR0):
    """
    im_arr: image as array
    M0: desired mean
    VAR0: desired variance

    G: normalized image as array
    """
    row, col = im_arr.shape
    # Mean and variance calculation
    M = (1 / (row ** 2)) * np.sum(im_arr)
    VAR = (1 / (row ** 2)) * np.sum((im_arr - M) ** 2)

    G = np.zeros(im_arr.shape)
    for i in range(row):
        for j in range(col):
            if im_arr[i, j] > M:
                G[i, j] = M0 + np.sqrt((VAR0 * (im_arr[i, j] - M) ** 2) / VAR)
            else:
                G[i, j] = M0 - np.sqrt((VAR0 * (im_arr[i, j] - M) ** 2) / VAR)
    return G

这是我用来读取数据的代码

data = 'greyfp.JPG'

img = Image.open(data).convert('L')
img = img.resize((200, 200))
img_arr = np.array(img).astype(float)
img_arr = img_arr / np.max(img_arr)

G = normalization(img_arr, 0.5, 0.5)

如果我现在检查新图像的均值和方差,我会得到想要的结果。但是当我尝试从其矩阵中绘制归一化指纹时,它看起来与输入图像完全相同

fig, ax = plt.subplots(1, 2)
grey = ax[0].imshow(img, cmap='gray')
norm = ax[1].imshow(G, cmap='gray')
plt.show()

但是,如果我保存新图像并绘制它

img = Image.fromarray(G, 'L')
img.save('G.JPG')
plt.imshow(img, cmap='gray')
plt.show()

它看起来 completely different,但仍然不像我想要的输出。

谁能帮我得到与论文中相同的结果,也许可以帮助我理解,为什么矩阵和图像类型的图看起来完全不同?

【问题讨论】:

  • 检查到G的形状;我有类似的问题,我的图像看起来像你的。那是我在一些图像操作之后改变了数组的大小。例如,我看到您调整了图像的大小。确保大小相同。
  • @asylumax 我不太确定我是否得到你。 G 和 img_arr 大小相同,即 (200, 200),因为我在读取图像时会调整图像大小。
  • 查看了你的代码; G 返回时是一个浮点数组;如果你乘以 255,然后转换为 uint8,你会得到一个图像。我想这可能是它,或者它的一部分。

标签: python image numpy python-imaging-library


【解决方案1】:

查看您的代码更新:

import numpy as np
from glob import glob
from PIL import Image
import matplotlib.pyplot as plt


def normalization(im_arr, M0, VAR0):
    """
    im_arr: image as array
    M0: desired mean
    VAR0: desired variance

    G: normalized image as array
    """
    row, col = im_arr.shape
    print("row,col = ", row, col)
    # Mean and variance calculation
    M = (1 / (row ** 2)) * np.sum(im_arr)
    VAR = (1 / (row ** 2)) * np.sum((im_arr - M) ** 2)

    G = np.zeros(im_arr.shape)
    for i in range(row):
        for j in range(col):

            if im_arr[i, j] > M:
                G[i, j] = M0 + np.sqrt((VAR0 * (im_arr[i, j] - M) ** 2) / VAR)
            else:
                G[i, j] = M0 - np.sqrt((VAR0 * (im_arr[i, j] - M) ** 2) / VAR)
    return G

data = 'test.jpg'

img = Image.open(data).convert('L')
img = img.resize((200, 200))
img_arr = np.array(img).astype(float)
img_arr = img_arr / np.max(img_arr)

G = normalization(img_arr, 0.5, 0.5)
G=G*255
G=np.where(G<=255,G,255)
G=np.array(G).astype(np.uint8)
cv2.imshow("G",G)


img = Image.fromarray(G, 'L')
img.save('G.JPG')
plt.imshow(img, cmap='gray')
plt.show()

【讨论】:

  • 这肯定会有所作为,尽管我无法重新创建所需的结果。我不完全理解为什么在我将输入读取为np.float 并将其重新调整为 0 和 1 之间的值之后需要将其转换为np.uint8。我也刚刚注意到,如果我使用任何plt.imshow(im_arr, cmap='gray')plt.imshow(img, cmap='gray') 它看起来不像我在最初的问题中发布的输入图片那么糟糕,但我不知道为什么。
  • 你需要乘以 255 并转换为 np.uint8,因为图像使用 0-255 作为像素缩放。顺便说一句,OpenCV 允许您直接查看这些数组,这有时很有用。
  • 我修改了代码来处理pixell值超过255的情况。这让事情看起来有很大不同。忘记加了!我认为这给出了一个合理的结果。
  • 到目前为止非常感谢!我认为这是朝着正确方向迈出的一步。但是,我仍然不确定如何获得与论文中相同的结果。另外,如果我想对标准化图像进行更多计算,是否将其保留为dtype = np.float?因为我的最终目标是获取指纹图像的方向图。
  • 好吧,如果你在做精细的缩放,把所有的东西都保留为浮点数,然后,转换成图像(0-255)进行显示。如果您摆弄 M0 和 VAR0 值,您就会开始看到差异,所以我想这就是事情变得有趣的地方。出于该计划的目的,我认为此解决方案可让您走上正轨。一张纸条;您应该嵌入这些示例图像,以便将来看到此内容的人可以了解整个情况(没有双关语)。外部链接可能会中断。
猜你喜欢
  • 2017-01-21
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多