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

标签 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

最佳答案

这是一个简单的问题,在转换之间不考虑数据类型。具体来说,当您加载图像时,它将是无符号的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

关于python - 如何将归一化图像数学方程转换为Python?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56462670/

相关文章:

Python 语句不按顺序执行?

python - 有没有办法使用 python 从 gmail 中提取内联图像?

python - 找到底部图像中黑色像素数量最多的最小平面。找到顶部图像黑色像素的峰值

python - 一次读2行

Python:将数据框写入现有的Excel,其中包含带有图像的工作表

python - 如何使用Python从outlook获取突出显示(选定)的邮件?

image - 无法通过 HTTPS 访问 Amazon S3 dzi 图像文件

html - 固定导航栏在滚动时被图像 slider 重叠

c++ - 用于 SVM OpenCV 训练的交通标志图像集

algorithm - 从视频中删除分段(例如人或鸟)的标准技术是什么?