Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Face Recognition Added #6

Open
wants to merge 19 commits into
base: revert-2-patch-1
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed 1.png
Binary file not shown.
207 changes: 141 additions & 66 deletions Aadhaar.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Mar 20 00:16:35 2020
Created on Fri Apr 24 20:01:19 2020

@author: utsav
@author: Kshitija Surange
"""


import cv2
from PIL import Image
import pytesseract
from pytesseract import Output
import re

import numpy as np
import math
from scipy import ndimage
import face_recognition
import uuid
import os

class Aadhaar_Card():
#Constructor
def __init__(self,config = {'orient' : True,'skew' : True,'crop': True,'contrast' : True,'psm': [3,4,6],'mask_color': (0, 165, 255), 'brut_psm': [6]}):
self.config = config
# Validates Aadhaar card numbers using Verhoeff Algorithm.
self.uuid=uuid.uuid4();
# Validates Aadhar card numbers using Verhoeff Algorithm.
# Fails if the fake number is generated using same Algorithm.
def validate(self,aadhaarNum):
def validate(self,aadharNum):

mult = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 0, 6, 7, 8, 9, 5], [2, 3, 4, 0, 1, 7, 8, 9, 5, 6],
[3, 4, 0, 1, 2, 8, 9, 5, 6, 7], [4, 0, 1, 2, 3, 9, 5, 6, 7, 8], [5, 9, 8, 7, 6, 0, 4, 3, 2, 1],
Expand All @@ -32,13 +39,13 @@ def validate(self,aadhaarNum):


try:
i = len(aadhaarNum)
i = len(aadharNum)
j = 0
x = 0

while i > 0:
i -= 1
x = mult[x][perm[(j % 8)][int(aadhaarNum[i])]]
x = mult[x][perm[(j % 8)][int(aadharNum[i])]]
j += 1
if x == 0:
return 1
Expand All @@ -56,6 +63,8 @@ def extract(self, path): #("path of input image")
self.image_path = path
self.read_image_cv()
if self.config['orient']:
self.cv_img = self.rotate(self.cv_img)
'''

try:
self.cv_img = self.rotate(self.cv_img)
Expand All @@ -67,6 +76,21 @@ def extract(self, path): #("path of input image")
os.remove('1_temp.png')

self.pil_img = self.pil_img.convert('RGBA')
'''

'''

try:
self.cv_img = self.rotate(self.cv_img)
except:
self.read_image_pil()
else:
self.cv_img.save('1_temp.png')
self.pil_img = Image.open('1_temp.png')
os.remove('1_temp.png')

self.pil_img = self.pil_img.convert('RGBA')
'''

if self.config['skew']:
print("skewness correction not available")
Expand All @@ -75,46 +99,51 @@ def extract(self, path): #("path of input image")
print("Smart Crop not available")

if self.config['contrast']:
self.pil_img = self.contrast_image(self.pil_img )

self.cv_img = self.contrast_image(self.cv_img)
#self.pil_img = self.contrast_image(self.pil_img )

print("correcting contrast")

aadhaars = set()
aadhars = set()
for i in range(len(self.config['psm'])):
t = self.text_extractor(self.pil_img,self.config['psm'][i])
anum = self.is_aadhaar_card(t)
t = self.text_extractor(self.cv_img,self.config['psm'][i])

anum = self.is_aadhar_card(t)

uid = self.find_uid(t)


if anum != "Not Found" and len(uid) == 0:
if len(anum) - anum.count(' ') == 12:
aadhaars.add(anum.replace(" ", ""))
aadhars.add(anum.replace(" ", ""))
if anum == "Not Found" and len(uid) != 0:

aadhaars.add(uid[0].replace(" ", ""))
aadhars.add(uid[0].replace(" ", ""))
if anum != "Not Found" and len(uid) != 0:
if len(anum) - anum.count(' ') == 12:
aadhaars.add(anum.replace(" ", ""))
aadhars.add(anum.replace(" ", ""))
#print(uid[0].strip())
aadhaars.add(uid[0].replace(" ", ""))
aadhars.add(uid[0].replace(" ", ""))

return list(aadhaars)
return list(aadhars)

def mask_image(self, path, write, aadhaar_list):
#print("Read Path => ", path, " write path => ",write, "aadhaar list =>",aadhaar_list)
def mask_image(self, path, write, aadhar_list):
#print("Read Path => ", path, " write path => ",write, "aadhar list =>",aadhar_list)
self.mask_count = 0
self.mask = cv2.imread(str(path), cv2.IMREAD_COLOR)
for j in range(len(self.config['psm'])):
for i in range(len(aadhaar_list)):
#print(" Runing mode: Aadhaar number:",aadhaar_list[i]," PSM => ",self.config['psm'][j])
if (self.mask_aadhaar(aadhaar_list[i],write,self.config['psm'][j]))>0:
for i in range(len(aadhar_list)):
#print(" Runing mode: Aadhar number:",aadhar_list[i]," PSM => ",self.config['psm'][j])
if (self.mask_aadhar(aadhar_list[i],write,self.config['psm'][j]))>0:
self.mask_count = self.mask_count + 1
#print(" :\/ ",self.mask_count)

#print("Final Mask Count =>",self.mask_count)
cv2.imwrite(write,self.mask)
return self.mask_count

def mask_aadhaar(self, uid, out_path, psm):
def mask_aadhar(self, uid, out_path, psm):
d = self.box_extractor(self.mask, psm)
n_boxes = len(d['level'])
color = self.config['mask_color'] #BGR
Expand All @@ -131,10 +160,12 @@ def mask_aadhaar(self, uid, out_path, psm):

def read_image_cv(self):
self.cv_img = cv2.imread(str(self.image_path), cv2.IMREAD_COLOR)


'''
def read_image_pil(self):
self.pil_img = Image.open(self.image_path)

'''

def mask_nums(self, input_file, output_file):
img = cv2.imread(str(input_file), cv2.IMREAD_COLOR)
for i in range(len(self.config['brut_psm'])): #'brut_psm': [6]
Expand All @@ -153,48 +184,93 @@ def mask_nums(self, input_file, output_file):

return "Done"


def rotate_only(self, img, angle_in_degrees):
self.img = img
self.angle_in_degrees = angle_in_degrees
rotated = ndimage.rotate(self.img, self.angle_in_degrees)
return rotated

def is_image_upside_down(self, img):
self.img = img
face_locations = face_recognition.face_locations(self.img)
encodings = face_recognition.face_encodings(self.img, face_locations)
image_is_upside_down = (len(encodings) == 0)
return image_is_upside_down

# Corrects orientation of image using tesseract OSD if rotation Angle is < 100.
def rotate(self,image, center = None, scale = 1.0):

rotate_angle=int(re.search('(?<=Rotate: )\d+', pytesseract.image_to_osd(image)).group(0))

if rotate_angle > 100:

img = Image.fromarray(image, 'RGB')
b, g, r = img.split()
img = Image.merge("RGB", (r, g, b))
return img
'''
def save_image(self, img):
self.img = img
cv2.imwrite('orientation_corrected.jpg', self.img)


def display(self, img, frameName="OpenCV Image"):
self.img = img
self.frameName = frameName
h, w = self.img.shape[0:2]
neww = 800
newh = int(neww*(h/w))
self.img = cv2.resize(self.img, (neww, newh))
cv2.imshow(self.frameName, self.img)
cv2.waitKey(0)
'''

# Corrects orientation of image using tesseract OSD if rotation Angle is < 100.
def rotate(self,img):
#def orientation_correction(img): #, save_image = False):
# GrayScale Conversion for the Canny Algorithm
self.img = img
img_gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
#self.display(img_gray)
# Canny Algorithm for edge detection was developed by John F. Canny not Kennedy!! :)
img_edges = cv2.Canny(img_gray, 100, 100, apertureSize=3)
#self.display(img_edges)
# Using Houghlines to detect lines
lines = cv2.HoughLinesP(img_edges, 1, math.pi / 180.0, 100, minLineLength=100, maxLineGap=5)
img_copy = self.img.copy()
for x in range(0, len(lines)):
for x1,y1,x2,y2 in lines[x]:
cv2.line(img_copy,(x1,y1),(x2,y2),(0,255,0),2)
#cv2.imshow('hough',img_copy)
#cv2.waitKey(0)

angles = []
for x1, y1, x2, y2 in lines[0]:
angle = math.degrees(math.atan2(y2 - y1, x2 - x1))
angles.append(angle)

# Getting the median angle
median_angle = np.median(angles)
# Rotating the image with this median angle
img_rotated = self.rotate_only(self.img, median_angle)
#self.display(img_rotated)

if self.is_image_upside_down(img_rotated):
print("rotate to 180 degree")
angle = -180
img_rotated_final = self.rotate_only(img_rotated, angle)
#self.save_image(img_rotated_final)
#self.display(img_rotated_final)
if self.is_image_upside_down(img_rotated_final):
print("Kindly check the uploaded image, face encodings still not found!")
return img_rotated
else:
print("image is now straight")
return img_rotated_final
else:
angle=360-int(re.search('(?<=Rotate: )\d+', pytesseract.image_to_osd(image)).group(0))
(h, w) = image.shape[:2]
#self.display(img_rotated)
print("image is straight")
return img_rotated

if center is None:
center = (w / 2, h / 2)

# Perform the rotation
M = cv2.getRotationMatrix2D(center, angle, scale)
rotated = cv2.warpAffine(image, M, (w, h))

img = Image.fromarray(rotated, 'RGB')
b, g, r = img.split()
img = Image.merge("RGB", (r, g, b))

return img

# Turns images BnW using pixels, didn't have much success with this and skipped in final production
def contrast_image(self, img):
pix = img.load()
# taking pixel value for using in ocr
for y in range(img.size[1]):
for x in range(img.size[0]):
if pix[x, y][0] < 102 or pix[x, y][1] < 102 or pix[x, y][2] < 102:
pix[x, y] = (0, 0, 0, 255)
else:
pix[x, y] = (255, 255, 255, 255)
return img
self.img = img
gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
#gray = cv2.bitwise_not(gray)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
#self.display(thresh)
return thresh

# Extracts Texts from images
def text_extractor(self, img, psm):
Expand Down Expand Up @@ -224,18 +300,17 @@ def find_uid(self,text2):
pass
return list(uid)

#Function to validate if an image contains text showing its an aadhaar card
def is_aadhaar_card(self, text):
#Function to validate if an image contains text showing its an aadhar card
def is_aadhar_card(self, text):
res=text.split()
aadhaar_number=''
aadhar_number=''
for word in res:
if len(word) == 4 and word.isdigit():
aadhaar_number=aadhaar_number + word + ' '
if len(aadhaar_number)>=14:
return aadhaar_number
aadhar_number=aadhar_number + word + ' '
if len(aadhar_number)>=14:
return aadhar_number

else:

return "Not Found"



Binary file added Aadhaar.pyc
Binary file not shown.
Binary file added DemoUI.mp4
Binary file not shown.
12 changes: 6 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

FROM debian:buster-slim as buildstage
LABEL maintainer="Utsav Mishra <https://festivitymishra.github.io/>"

Expand All @@ -14,15 +13,16 @@ RUN apt-get update && \
# Build Python APP Here
RUN mkdir aadhaar_ocr_masking

COPY requirements.txt /aadhaar_ocr_masking/requirements.txt
RUN pip install -r /aadhaar_ocr_masking/requirements.txt

COPY Aadhaar.py /aadhaar_ocr_masking/Aadhaar.py
COPY app.py /aadhaar_ocr_masking/app.py
COPY requirements.txt /aadhaar_ocr_masking/requirements.txt

RUN cd aadhaar_ocr_masking && \
pip install -r requirements.txt
RUN mkdir /aadhaar_ocr_masking/temp
RUN mkdir /aadhaar_ocr_masking/public

WORKDIR /aadhaar_ocr_masking
COPY public/* /aadhaar_ocr_masking/public/

WORKDIR /aadhaar_ocr_masking
CMD ["python", "app.py"]

Loading