简体   繁体   中英

How to Transform Normalization Image Math Equation to Python?

I try to learn how to transform equation to python script.

I choose to start it from FingerPrint Enhancement from Academic resources here .

to start learn i search a fingerprint image to be enhance. I choose this image :

在此处输入图片说明

so, i do the first step is converting to gray:

import cv2
import numpy as np

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

and below is the result: 在此处输入图片说明

ok the problem start from here...

please try to understood me, I try to learn how to convert math equation to python script. not try to looking for another / existing script in Github (for example).

the equation is: 在此处输入图片说明

all detail from the academic research . Told that: Let I(i, j) denote the gray-level value at pixel (i, j), M and VAR denote the estimated mean and variance of I, respectively, and G(i, j) denote the normalized gray-level value at pixel (i, j). A gray-level fingerprint image, I is defined as an N x N matrix, where I(i, j) represents the intensity of the pixel at the i-th row and j-th column. We assume that all the images are scanned at a resolution of 500 dots per inch (dpi). The mean and variance of a gray-level fingerprint image, I, are defined as

在此处输入图片说明

and 在此处输入图片说明 respectively

ok, we start to transform the equation:

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)

the result is out of expected: 在此处输入图片说明

all is white.

can somebody help me? please your advise.

to remind you, I'm not try to looking for the another script / another example . I try to understood how to transform a math equation to python script . about another script, i already have, even i already map it here .

This is a simple problem of not respecting the data types in between transformations. Specifically, when you load in the image, it is going to be unsigned 8-bit integer so the expected values should be within [0, 255] , yet your calculations for the mean and variance will exceed this dynamic range and thus your calculations will overflow. The quickest way to resolve this problem is to convert your image so that it will respect a data type that can handle the precision of the calculations you want, like floating-point. Perform the calculations, and when you're done convert the image back to the expected data type, so unsigned 8-bit integer.

In addition, there are several errors in your code. For one thing, you didn't provide the variable N , which should be the total number of pixels in the image. In addition, your var function accepts gray as the variable yet you are using img to try and access pixel data, so this will also give off an error when you try and run it. Finally, you omitted the packages you're using so I added these in.

I've also downloaded your image locally so I can run the code to verify that it works. I've patched up the end of your code so that the image window that displays the result properly closes after you push a key and I've written the output image to file.

Therefore:

# 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)

The output image we get is:

产量

I didn't run your code but make sure G0 or G1 doesn't get too big. It could be that your value is above 255, thus the resulting all-white image.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM