Logo elodees  elodees

A caring AI for a better world













Only alphabetic characters accented or not as well as the space are accepted

Logo IA




Fingerprint





No account yet ?

Sign up to access all content


Tested in Anaconda and Python 3.7

import matplotlib.pyplot as plt
import cv2
 
def showimage(myimage, figsize=[10,10]):
    if (myimage.ndim>2):  #This only applies to RGB or RGBA images (e.g. not to Black and White images)
        myimage = myimage[:,:,::-1] #OpenCV follows BGR order, while matplotlib likely follows RGB order
 
    fig, ax = plt.subplots(figsize=figsize)
    ax.imshow(myimage, cmap = 'gray', interpolation = 'bicubic')
    plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
    plt.show()
 
"load image data"
Img_Original =  cv2.imread( 'Emprunte-digitale-01.jpg', 0)      # Gray image, rgb images need pre-conversion
showimage(Img_Original)
 
from skimage.filters import threshold_otsu
 
Otsu_Threshold = threshold_otsu(Img_Original)   
BW_Original = Img_Original > Otsu_Threshold    # must set object region as 1, background region as 0 !
 
from skimage.morphology import skeletonize
BW_Skeleton = skeletonize(BW_Original)
showimage(BW_Skeleton)
 


Original image

Free image provided by pexel.com

Skeleton image

Free image provided by pexel.com


Tested in Anaconda and Python 3.7

import cv2 as cv
from matplotlib import pyplot as plt
 
def showimage(myimage, figsize=[10,10]):
    if (myimage.ndim>2):  #This only applies to RGB or RGBA images (e.g. not to Black and White images)
        myimage = myimage[:,:,::-1] #OpenCV follows BGR order, while matplotlib likely follows RGB order
 
    fig, ax = plt.subplots(figsize=figsize)
    ax.imshow(myimage, cmap = 'gray', interpolation = 'bicubic')
    plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
    plt.show()
 
from skimage.filters import threshold_otsu
from skimage.filters import threshold_yen
from skimage.filters import threshold_li
 
img = cv.imread( 'Emprunte-digitale-01.jpg', 0)
showimage(img)
 
Otsu_Threshold = threshold_otsu(img)   
th1 = img > Otsu_Threshold
showimage(th1)
 
Yen_Threshold = threshold_yen(img)   
th2 = img > Yen_Threshold
showimage(th2)
 
Li_Threshold = threshold_li(img)   
th3 = img > Li_Threshold
showimage(th3)
 
ret,th4 = cv.threshold(img,127,255,cv.THRESH_BINARY)
showimage(th4)
 
th5 = cv.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY,11,2)
showimage(th5)
 


Original image

Free image provided by pexel.com

Otsu thresholding

Free image provided by pexel.com

Yen thresholding

Free image provided by pexel.com

Li thresholding

Free image provided by pexel.com

Global thresholding

Free image provided by pexel.com

Adaptative thresholding

Free image provided by pexel.com








Tested in Anaconda and Python 3.7

import numpy as np
import cv2
import matplotlib.pyplot as plt
import skimage.io as io
import skimage.morphology
 
from PIL import Image, ImageDraw
from skimage.filters import threshold_otsu, threshold_yen, threshold_li 
from skimage.morphology import convex_hull_image, erosion, square, skeletonize
 
def getTerminationBifurcation(img, mask):
 
    img = img == 255;
    (rows, cols) = img.shape;
    minutiaeTerm = np.zeros(img.shape);
    minutiaeBif = np.zeros(img.shape);
 
    for i in range(1,rows-1):
        for j in range(1,cols-1):
            if(img[i][j] == 1):
                block = img[i-1:i+2,j-1:j+2];
                block_val = np.sum(block);
                if(block_val == 2):
                    minutiaeTerm[i,j] = 1;
 
                elif(block_val == 4):
                    minutiaeBif[i,j] = 1;
 
    mask = convex_hull_image(mask>0)
    mask = erosion(mask, square(5))         # Structuing element for mask erosion = square(5)
    minutiaeTerm = np.uint8(mask)*minutiaeTerm
 
    return(minutiaeTerm, minutiaeBif)
 
def removeSpuriousMinutiae(minutiaeList, img, thresh):
    img = img * 0;
    SpuriousMin = [];
    numPoints = len(minutiaeList);
    D = np.zeros((numPoints, numPoints))
    for i in range(1,numPoints):
        for j in range(0, i):
            (X1,Y1) = minutiaeList[i]['centroid']
            (X2,Y2) = minutiaeList[j]['centroid']
 
            dist = np.sqrt((X2-X1)**2 + (Y2-Y1)**2);
            D[i][j] = dist
            if(dist < thresh):
                SpuriousMin.append(i)
                SpuriousMin.append(j)
 
    SpuriousMin = np.unique(SpuriousMin)
    for i in range(0,numPoints):
        if(not i in SpuriousMin):
            (X,Y) = np.int16(minutiaeList[i]['centroid']);
            img[X,Y] = 1;
 
    img = np.uint8(img);
    return(img)
 
"load image data"
Img_Original =  io.imread('Original.bmp')
 
imgplot = plt.imshow(Img_Original, 'gray')
plt.axis('off')
plt.show()
 
Otsu_Threshold = threshold_otsu(Img_Original)   
BW_Original = Img_Original > Otsu_Threshold
 
imgplot = plt.imshow(BW_Original, 'gray')
plt.axis('off')
plt.imsave('BW-Original.jpg', BW_Original, cmap='gray')
plt.show()
 
BW_Skeleton = skeletonize(BW_Original)
 
imgplot = plt.imshow(BW_Skeleton, 'gray')
plt.axis('off')
plt.imsave('skeleton.jpg', BW_Skeleton, cmap='gray')
plt.show()
 
Otsu_Threshold = threshold_otsu(Img_Original)   
th1 = Img_Original > Otsu_Threshold
 
Yen_Threshold = threshold_yen(Img_Original)   
th2 = Img_Original > Yen_Threshold
 
Li_Threshold = threshold_li(Img_Original)   
th3 = Img_Original > Li_Threshold
 
ret,th4 = cv2.threshold(Img_Original,127,255,cv2.THRESH_BINARY)
th5 = cv2.adaptiveThreshold(Img_Original,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
            cv2.THRESH_BINARY,11,2)
 
# plot all the images and their histograms
images = [th1,
          th2,
          th3,
          th4,
          th5]
 
titles = ['Ots-Threshold',
          "Yen-Threshold",
          "Li-Threshold",
          "Global-Threshold",
          "Adaptive-Threshold"]
 
for i in range(5):
    imgplot = plt.imshow(images[i], 'gray')
    plt.axis('off')
    plt.title(titles[i])
    plt.imsave('%s.jpg' % (titles[i]), images[i], cmap='gray')
    plt.show()
 
img = Image.open('skeleton.jpg').convert('L')
 
Img_Original = img
 
# To reach different pixels from given pixel ....
 
cells = [(-1, -1), (-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1)]
 
# Function to determine type of minutiae at pixel P(i,j) ....
 
def minutiae_at(pixels, i, j):
    values = [pixels[i + k][j + l] for k, l in cells]
 
    crossings = 0
    for k in range(0, 8):
        crossings += abs(values[k] - values[k + 1])
    crossings /= 2
 
    if pixels[i][j] == 1:
        if crossings == 1:
            return "ending"
        if crossings == 3:
            return "bifurcation"
    return "none"
 
# Function to convert the image into pixels ....
 
def load_image(im):
    (x,y) = im.size
    im_load = im.load()
 
    result = []
    for i in range(0, x):
        result.append([])
        for j in range(0, y):
            result[i].append(im_load[i, j])
 
    return result
 
# Function to apply particular property to each pixel ....
 
def apply_to_each_pixel(pixels, f):
    for i in range(0, len(pixels)):
        for j in range(0, len(pixels[i])):
            pixels[i][j] = f(pixels[i][j])
 
# Function to show minutiae on the image ....
 
def show_minutiaes(im):
    pixels = load_image(im)
    apply_to_each_pixel(pixels, lambda x: 0.0 if x > 10 else 1.0)
 
    (x, y) = im.size
    result = im.convert("RGB")
 
    draw = ImageDraw.Draw(result)
 
    colors = {"ending" : (150, 0, 0), "bifurcation" : (0, 150, 0)}
 
    ellipse_size = 8
    for i in range(1, x - 1):
        for j in range(1, y - 1):
            minutiae = minutiae_at(pixels, i, j)
            if minutiae != "none":
                draw.ellipse([(i - ellipse_size, j - ellipse_size), (i + ellipse_size, j + ellipse_size)], outline = colors[minutiae])
 
    del draw
 
    return result
 
# Applying Minutiae Detection Algorithm to image ....
Minutiae_Image = show_minutiaes(img)
 
# Displaying the results ....
 
imgplot = plt.imshow(Img_Original, 'gray')
plt.axis('off')
plt.title('Original image')
plt.show()
 
imgplot = plt.imshow(Minutiae_Image)
plt.axis('off')
plt.title('Minutiae in the image')
plt.show()
 
Minutiae_Image.save('Minutiae.jpg')
 
img = cv2.imread('Original.bmp', 0)
img = np.uint8(img > 128)
 
skel = skimage.morphology.skeletonize(img)
skel = np.uint8(skel)*255;
 
mask = skel*255;
 
(minutiaeTerm, minutiaeBif) = getTerminationBifurcation(skel, mask);
 
minutiaeTerm = skimage.measure.label(minutiaeTerm, 8);
RP = skimage.measure.regionprops(minutiaeTerm)
minutiaeTerm = removeSpuriousMinutiae(RP, np.uint8(img), 10);
 
BifLabel = skimage.measure.label(minutiaeBif, 8);
TermLabel = skimage.measure.label(minutiaeTerm, 8);
 
minutiaeBif = minutiaeBif * 0;
minutiaeTerm = minutiaeTerm * 0;
 
(rows, cols) = skel.shape
DispImg = np.zeros((rows,cols,3), np.uint8)
DispImg[:,:,0] = skel; DispImg[:,:,1] = skel; DispImg[:,:,2] = skel;
 
 
RP = skimage.measure.regionprops(BifLabel)
for i in RP:
    (row, col) = np.int16(np.round(i['Centroid']))
    minutiaeBif[row, col] = 1;
    (rr, cc) = skimage.draw.circle_perimeter(row, col, 3);
    skimage.draw.set_color(DispImg, (rr,cc), (255,0,0));
 
 
RP = skimage.measure.regionprops(TermLabel)
for i in RP:
    (row, col) = np.int16(np.round(i['Centroid']))
    minutiaeTerm[row, col] = 1;
    (rr, cc) = skimage.draw.circle_perimeter(row, col, 3);
    skimage.draw.set_color(DispImg, (rr,cc), (0, 0, 255));
 
 
plt.imshow(DispImg)
plt.axis('off')
plt.title('Minutiae image')
plt.imsave('Minutiae-image.jpg', DispImg)
plt.show()
 


Original image

Free image provided by pexel.com

Grayscale

Free image provided by pexel.com

Skeletonization

Free image provided by pexel.com


Ots thresholding

Free image provided by pexel.com

Yen thresholding

Free image provided by pexel.com

Li thresholding

Free image provided by pexel.com


Global thresholding

Free image provided by pexel.com

Adaptative thresholding

Free image provided by pexel.com

Minutiae

Free image provided by pexel.com


Minutiae in the image

Free image provided by pexel.com


Minutiae-Extraction - GitHub













Welcome, my name is Eric Soupet and I am the administrator of the site elodees.com. elodees.com is a state of the art of Artificial Intelligence and aims to be collaborative, you can now offer content such as articles, events, tutorials, ... so don't hesitate !

Platform images credit : Pixabay - Pixabay License | Pexels - Pexels License