Search code examples
python-3.xpython-imaging-libraryfingerprint

How to convert list of integers to image?


I am using a SFM5020 fingerprint scanner and I am using pysfm library. I have a function that reads fingerprint data and gives template data of length 10909 in the form of a list. I want to convert it to an image. Can you please help me on this?

I don't know the height and width, I just know the length of the template data which is 10909. Here's a section of such template data:

template_data = [16, 1, 0, 0, 64, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 84, 1, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 15, 255, 63, 240, 199, 127, 255, 23, 255, 255, 31, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 31, 249, 255, 255, 255, 255, 227, 127, 224, 15, 254, 248, 7, 254, 247, 31, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ,.................................. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0]

Can you please help me convert template_data to an image?


Solution

  • Here comes an educated guess, which was too long for a comment.

    From the specifications, the SFM5020 has an image size of 272 x 320. That'd be 87.040 pixels in total. You have 10.909 bytes of data, which is 87.272 bits. So, it seems, the pixel data is stored as binary, i.e. each byte represents eight consecutive pixels.

    Now, you have 29 additional bytes (87.272 bits - 87.040 pixels = 232 bits = 29 bytes). Let's have a look on your template_data: The first 28 bytes are more or less zeros. Starting from byte 29, there are a lot of ones. That's maybe "white" background. Looking at the end, you have a single zero. Before, there's also a lot of "white". So, most likely, discard the first 28 bytes and the last byte to extract the actual fingerprint data.

    With the example given and under the assumption, that data is continuous per row, we can extract two rows:

    import numpy as np
    from PIL import Image
    
    # Data
    head = [16, 1, 0, 0, 64, 1, 0, 0,                   # Byte 0 - 7
            0, 0, 0, 0, 0, 0, 0, 0,                     # Byte 8 - 15
            1, 0, 0, 0, 0, 84, 1, 0,                    # Byte 16 - 23
            0, 0, 0, 0, 255, 255, 255, 255,             # Byte 24 - 31
            255, 255, 255, 255, 255, 255, 255, 255,     # ...
            15, 255, 63, 240, 199, 127, 255, 23,
            255, 255, 31, 255, 255, 255, 255, 255,
            255, 255, 255, 255, 255, 255, 255, 255,
            255, 255, 255, 255, 255, 31, 249, 255,
            255, 255, 255, 227, 127, 224, 15, 254,
            248, 7, 254, 247, 31, 255, 255, 255,
            255, 255, 255, 255, 255, 255, 255,
            255, 255]
    # ... Rest of the data...
    tail = [255, 255, 255, 255, 255, 255, 255, 255,     # Byte 10896 - 10903
            255, 255, 255, 255, 0]                      # Byte 10904 - 10908
    
    # Unpack bits from bytes starting from byte 28
    bits = np.unpackbits(np.array(head[28:len(head)]).astype(np.uint8)) * 255
    #bits = np.unpackbits(np.array(template_data[28:-1]).astype(np.uint8)) * 255
    
    # SFM5020 has image size of 272 x 320
    # https://www.supremainc.com/embedded-modules/en/modules/sfm-5000.asp
    w = 272
    h = 320
    
    # Extract fingerprint data from bits
    fp = bits[0:2*w].reshape((2, w))
    # fp = bits[0:h*w].reshape((h, w))
    
    # Save fingerprint as image via Pillow/PIL
    fp_pil = Image.fromarray(fp, 'L')
    fp_pil.save('fp.png')
    

    The saved image (via Pillow/PIL regarding your tags) would look like this:

    Output

    I can't tell, if that's the beginning of a proper fingerprint. Maybe, just try the above code on your actual template_data. Therefore, uncomment the two lines given. If the fingerprint looks strange, try fp = bits[0:h*w].reshape((w, h)).T. That'd mean, that fingerprint data is stored continuous per column.

    Hope that helps!

    ----------------------------------------
    System information
    ----------------------------------------
    Platform:    Windows-10-10.0.16299-SP0
    Python:      3.8.1
    NumPy:       1.18.1
    Pillow:      7.0.0
    ----------------------------------------