如何将归一化图像数学方程式转换为Python?

时间:2019-06-05 14:34:27

标签: python image opencv image-processing

我尝试学习如何将方程式转换为python脚本。

我选择从学术资源here的“指纹增强”功能开始。

开始学习,我将搜索指纹图像以进行增强。我选择此image

enter image description here

所以,我要做的第一步是转换为灰色:

import cv2
import numpy as np

input = 'PATH OF IMAGE'
img = cv2.imread(input)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

,结果如下: enter image description here

好,问题从这里开始...

请尝试理解我,我尝试学习如何将数学方程式转换为python脚本。 不要尝试在Github中查找其他/现有脚本(例如)。

等式是: enter image description here

academic research中的所有详细信息。告知: 令I(i,j)表示像素(i,j),M和 VAR分别表示I的估计均值和方差,G(i,j)表示像素(i,j)的归一化灰度值。 灰度指纹图像I定义为N x N矩阵,其中I(i,j)表示像素在像素点的强度。 第i行和第j列。我们假设所有图像都是 以每英寸500点(dpi)的分辨率进行扫描。灰度指纹图像I的均值和方差定义为

enter image description here

enter image description here 分别

好的,我们开始变换方程式

def mean(gray):
    rows, cols = gray.shape
    sum = 0
    for i in range(0,rows):
        for j in range(0, cols):
            pix = (gray[i,j].item())
            sum += pix
    M = sum/N
    return M

def var(gray, M):
    rows, cols = gray.shape
    N = gray.size
    sum = 0
    for i in range(0,rows):
        for j in range(0, cols):
            vix = ((img[i,j].item()) - M)**2
            sum += vix
    VAR = sum/N
    return VAR

def normalize(img, M0, VAR0):
    M = mean(img)
    VAR = var(img, M)
    rows,cols = img.shape
    normim = np.zeros((rows, cols))
    for i in range(0, rows):
        for j in range(0, cols):
            if (gray[i,j].item()) > M:
                G0 = M0 + ((((VAR0)*(((gray[i,j].item())-(M))**2))/(VAR))**(1/2))
                normim[i,j] = int(G0)
            else:
                G1 = M0 - ((((VAR0)*(((gray[i,j].item())-(M))**2))/(VAR))**(1/2))
                normim[i,j] = int(G1)
    return normim


M0 = 100 #follow the academic research document
VAR0 = 100 #follow the academic research document
normgray = normalize(gray, 100,100)

cv2.imshow('test', normgray)
cv2.waitKey(1)

结果超出预期: enter image description here

都是白色的。

有人可以帮我吗?请您咨询。

提醒您,我不是在寻找另一个脚本/另一个示例我试图理解如何将数学方程式转换为python脚本。关于另一个脚本,我已经拥有,甚至我已经将其映射为here

2 个答案:

答案 0 :(得分:1)

这是一个不考虑转换之间的数据类型的简单问题。具体来说,当您加载图片时,它将是8位无符号整数,因此期望值应在[0, 255]之内,但是您的均值和方差计算将超出此动态范围,因此您的计算将溢出。解决此问题的最快方法是转换图像,使其遵循可以处理所需计算精度的数据类型,例如浮点数。执行计算,完成后将图像转换回期望的数据类型,即无符号的8位整数。

此外,您的代码中有几个错误。一方面,您没有提供变量N,该变量应该是图像中的像素总数。另外,您的var函数接受gray作为变量,但您正在使用img尝试访问像素数据,因此在尝试运行它时也会产生错误。最后,您省略了正在使用的软件包,因此我将它们添加了。

我还从本地下载了您的图片,因此我可以运行代码以验证其是否有效。我已经修补了代码的结尾,以便在按下键并将输出图像写入文件后,可以正确关闭显示结果的图像窗口。

因此:

# Added so the code can run
import cv2
import numpy as np

# Added so the code can run
gray = cv2.imread('gnN4Q.png', 0)
gray = gray.astype(np.float) # Change to floating-point
N = gray.shape[0]*gray.shape[1]

def mean(gray):
    rows, cols = gray.shape
    sum = 0
    for i in range(0,rows):
        for j in range(0, cols):
            pix = (gray[i,j].item())
            sum += pix
    M = sum/N # Added above
    return M

def var(gray, M):
    rows, cols = gray.shape
    N = gray.size
    sum = 0
    for i in range(0,rows):
        for j in range(0, cols):
            vix = ((gray[i,j].item()) - M)**2 # Change
            sum += vix
    VAR = sum/N
    return VAR

def normalize(img, M0, VAR0):
    M = mean(img)
    VAR = var(img, M)
    rows,cols = img.shape
    normim = np.zeros((rows, cols))
    for i in range(0, rows):
        for j in range(0, cols):
            if (gray[i,j].item()) > M:
                G0 = M0 + ((((VAR0)*(((gray[i,j].item())-(M))**2))/(VAR))**(1/2))
                normim[i,j] = int(G0)
            else:
                G1 = M0 - ((((VAR0)*(((gray[i,j].item())-(M))**2))/(VAR))**(1/2))
                normim[i,j] = int(G1)
    return normim

M0 = 100 #follow the academic research document
VAR0 = 100 #follow the academic research document
normgray = normalize(gray, 100,100)
normgray = normgray.astype(np.uint8) # Added - convert back to uint8
cv2.imshow('test', normgray)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('output.png', normgray)

我们得到的输出图像是:

Output

答案 1 :(得分:0)

我没有运行您的代码,但请确保G0或G1不会太大。可能是您的值大于255,因此得到的全白图像。