How to Enhance Fingerprint Images Without Blurring Ridges? i am using django [closed]

How to Enhance Fingerprint Images Without Blurring Ridges? i am using django.
I’m currently working on a fingerprint enhancement project using OpenCV, and while my code is producing results, the ridges in the fingerprint images are coming out blurred.
here is my code

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>import cv2
import numpy as np
import math
import fingerprint_enhancer # Ensure this module is available
from django.shortcuts import render
from django.core.files.base import ContentFile
from .forms import HandFingerForm
from .models import ThumbImage
import base64
MAX_IMAGES = 10
def remove_green(img):
empty_img = np.zeros_like(img)
RED, GREEN, BLUE = (2, 1, 0)
reds = img[:, :, RED]
greens = img[:, :, GREEN]
blues = img[:, :, BLUE]
# Create a mask for the areas to keep
tmpMask = (greens < 35) | (reds > greens) | (blues > greens)
img[tmpMask == 0] = (0, 0, 0) # Remove background from original picture
empty_img[tmpMask] = (255, 255, 255) # Mask with finger in white
return img, empty_img
def detect_nail(gray_mask_finger):
# Find contours in the mask image
contours, _ = cv2.findContours(gray_mask_finger, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
# Only consider large enough contours as nails
if cv2.contourArea(contour) > 100: # Adjust this threshold as needed
x, y, w, h = cv2.boundingRect(contour)
# Draw a rectangle around the detected nail
cv2.rectangle(gray_mask_finger, (x, y), (x + w, y + h), (255, 0, 0), 2) # Blue rectangle
def process_fingerprint(image):
clip_hist_percent = 25
# Convert to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Calculate grayscale histogram
hist = cv2.calcHist([gray], [0], None, [256], [0, 256])
hist_size = len(hist)
# Calculate cumulative distribution from the histogram
accumulator = []
accumulator.append(float(hist[0]))
for index in range(1, hist_size):
accumulator.append(accumulator[index - 1] + float(hist[index]))
# Locate points to clip
maximum = accumulator[-1]
clip_hist_percent *= (maximum / 100.0)
clip_hist_percent /= 2.0
# Locate left cut
minimum_gray = 0
while accumulator[minimum_gray] < clip_hist_percent:
minimum_gray += 1
# Locate right cut
maximum_gray = hist_size - 1
while accumulator[maximum_gray] >= (maximum - clip_hist_percent):
maximum_gray -= 1
# Calculate alpha and beta values
alpha = 255 / (maximum_gray - minimum_gray)
beta = -minimum_gray * alpha
auto_result = cv2.convertScaleAbs(image, alpha=alpha, beta=beta)
gray = cv2.cvtColor(auto_result, cv2.COLOR_BGR2GRAY)
# Compute gamma
mid = 0.5
mean = np.mean(gray)
gamma = math.log(mid * 255) / math.log(mean)
# Apply gamma correction
img_gamma = np.power(auto_result, gamma).clip(0, 255).astype(np.uint8)
g1 = cv2.cvtColor(img_gamma, cv2.COLOR_BGR2GRAY)
# Adaptive thresholding
thresh2 = cv2.adaptiveThreshold(g1, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 199, 3)
# Morphological operations
blur = ((3, 3), 1)
erode_ = (5, 5)
dilate_ = (3, 3)
dilate = cv2.dilate(cv2.erode(cv2.GaussianBlur(thresh2 / 255, blur[0], blur[1]),
np.ones(erode_)), np.ones(dilate_)) * 255
# Enhance fingerprint
out = fingerprint_enhancer.enhance_Fingerprint(dilate)
return out
def upload_image(request):
if 'upload_count' not in request.session:
request.session['upload_count'] = 0
upload_count = request.session['upload_count']
if request.method == 'POST':
if 'skip' in request.POST:
request.session['upload_count'] = 0
return render(request, 'captureimage.html', {
'message': 'Skipped the remaining uploads.',
'next_finger': None,
'max_images': MAX_IMAGES
})
finger_number = request.POST.get('finger')
image_data = request.POST.get('image')
if not image_data or ';base64,' not in image_data:
return render(request, 'captureimage.html', {
'error': 'Invalid image data',
'next_finger': upload_count + 1,
'max_images': MAX_IMAGES
})
try:
format, imgstr = image_data.split(';base64,')
except ValueError:
return render(request, 'captureimage.html', {
'error': 'Failed to parse image data',
'next_finger': upload_count + 1,
'max_images': MAX_IMAGES
})
ext = format.split('/')[-1]
image_file = ContentFile(base64.b64decode(imgstr), name=f'finger_{finger_number}.{ext}')
form_data = {'finger': finger_number}
form_files = {'image': image_file}
form = HandFingerForm(form_data, form_files)
if form.is_valid():
form.save()
# Load and process the saved image
saved_image_path = form.instance.image.path
image = cv2.imread(saved_image_path, 1) # Load the image
image = cv2.resize(image, None, fx=0.3, fy=0.3) # Resize
image = cv2.GaussianBlur(image, (3, 3), 0) # Apply Gaussian blur
# Process fingerprint
enhanced_image = process_fingerprint(image)
# Remove green background
no_green_image, mask_finger = remove_green(enhanced_image)
# Convert to grayscale
gray_mask_finger = cv2.cvtColor(mask_finger, cv2.COLOR_BGR2GRAY)
# Call the function to detect nail
detect_nail(gray_mask_finger)
request.session['upload_count'] += 1
if request.session['upload_count'] < MAX_IMAGES:
return render(request, 'captureimage.html', {
'message': 'Finger image uploaded successfully.',
'next_finger': request.session['upload_count'] + 1,
'max_images': MAX_IMAGES
})
else:
request.session['upload_count'] = 0
return render(request, 'captureimage.html', {
'message': 'All 10 images uploaded successfully!',
'next_finger': None,
'max_images': MAX_IMAGES
})
else:
return render(request, 'captureimage.html', {
'error': 'Invalid form data',
'details': form.errors,
'next_finger': upload_count + 1,
'max_images': MAX_IMAGES
})
return render(request, 'captureimage.html', {
'next_finger': request.session['upload_count'] + 1,
'max_images': MAX_IMAGES
})
</code>
<code>import cv2 import numpy as np import math import fingerprint_enhancer # Ensure this module is available from django.shortcuts import render from django.core.files.base import ContentFile from .forms import HandFingerForm from .models import ThumbImage import base64 MAX_IMAGES = 10 def remove_green(img): empty_img = np.zeros_like(img) RED, GREEN, BLUE = (2, 1, 0) reds = img[:, :, RED] greens = img[:, :, GREEN] blues = img[:, :, BLUE] # Create a mask for the areas to keep tmpMask = (greens < 35) | (reds > greens) | (blues > greens) img[tmpMask == 0] = (0, 0, 0) # Remove background from original picture empty_img[tmpMask] = (255, 255, 255) # Mask with finger in white return img, empty_img def detect_nail(gray_mask_finger): # Find contours in the mask image contours, _ = cv2.findContours(gray_mask_finger, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for contour in contours: # Only consider large enough contours as nails if cv2.contourArea(contour) > 100: # Adjust this threshold as needed x, y, w, h = cv2.boundingRect(contour) # Draw a rectangle around the detected nail cv2.rectangle(gray_mask_finger, (x, y), (x + w, y + h), (255, 0, 0), 2) # Blue rectangle def process_fingerprint(image): clip_hist_percent = 25 # Convert to grayscale gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Calculate grayscale histogram hist = cv2.calcHist([gray], [0], None, [256], [0, 256]) hist_size = len(hist) # Calculate cumulative distribution from the histogram accumulator = [] accumulator.append(float(hist[0])) for index in range(1, hist_size): accumulator.append(accumulator[index - 1] + float(hist[index])) # Locate points to clip maximum = accumulator[-1] clip_hist_percent *= (maximum / 100.0) clip_hist_percent /= 2.0 # Locate left cut minimum_gray = 0 while accumulator[minimum_gray] < clip_hist_percent: minimum_gray += 1 # Locate right cut maximum_gray = hist_size - 1 while accumulator[maximum_gray] >= (maximum - clip_hist_percent): maximum_gray -= 1 # Calculate alpha and beta values alpha = 255 / (maximum_gray - minimum_gray) beta = -minimum_gray * alpha auto_result = cv2.convertScaleAbs(image, alpha=alpha, beta=beta) gray = cv2.cvtColor(auto_result, cv2.COLOR_BGR2GRAY) # Compute gamma mid = 0.5 mean = np.mean(gray) gamma = math.log(mid * 255) / math.log(mean) # Apply gamma correction img_gamma = np.power(auto_result, gamma).clip(0, 255).astype(np.uint8) g1 = cv2.cvtColor(img_gamma, cv2.COLOR_BGR2GRAY) # Adaptive thresholding thresh2 = cv2.adaptiveThreshold(g1, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 199, 3) # Morphological operations blur = ((3, 3), 1) erode_ = (5, 5) dilate_ = (3, 3) dilate = cv2.dilate(cv2.erode(cv2.GaussianBlur(thresh2 / 255, blur[0], blur[1]), np.ones(erode_)), np.ones(dilate_)) * 255 # Enhance fingerprint out = fingerprint_enhancer.enhance_Fingerprint(dilate) return out def upload_image(request): if 'upload_count' not in request.session: request.session['upload_count'] = 0 upload_count = request.session['upload_count'] if request.method == 'POST': if 'skip' in request.POST: request.session['upload_count'] = 0 return render(request, 'captureimage.html', { 'message': 'Skipped the remaining uploads.', 'next_finger': None, 'max_images': MAX_IMAGES }) finger_number = request.POST.get('finger') image_data = request.POST.get('image') if not image_data or ';base64,' not in image_data: return render(request, 'captureimage.html', { 'error': 'Invalid image data', 'next_finger': upload_count + 1, 'max_images': MAX_IMAGES }) try: format, imgstr = image_data.split(';base64,') except ValueError: return render(request, 'captureimage.html', { 'error': 'Failed to parse image data', 'next_finger': upload_count + 1, 'max_images': MAX_IMAGES }) ext = format.split('/')[-1] image_file = ContentFile(base64.b64decode(imgstr), name=f'finger_{finger_number}.{ext}') form_data = {'finger': finger_number} form_files = {'image': image_file} form = HandFingerForm(form_data, form_files) if form.is_valid(): form.save() # Load and process the saved image saved_image_path = form.instance.image.path image = cv2.imread(saved_image_path, 1) # Load the image image = cv2.resize(image, None, fx=0.3, fy=0.3) # Resize image = cv2.GaussianBlur(image, (3, 3), 0) # Apply Gaussian blur # Process fingerprint enhanced_image = process_fingerprint(image) # Remove green background no_green_image, mask_finger = remove_green(enhanced_image) # Convert to grayscale gray_mask_finger = cv2.cvtColor(mask_finger, cv2.COLOR_BGR2GRAY) # Call the function to detect nail detect_nail(gray_mask_finger) request.session['upload_count'] += 1 if request.session['upload_count'] < MAX_IMAGES: return render(request, 'captureimage.html', { 'message': 'Finger image uploaded successfully.', 'next_finger': request.session['upload_count'] + 1, 'max_images': MAX_IMAGES }) else: request.session['upload_count'] = 0 return render(request, 'captureimage.html', { 'message': 'All 10 images uploaded successfully!', 'next_finger': None, 'max_images': MAX_IMAGES }) else: return render(request, 'captureimage.html', { 'error': 'Invalid form data', 'details': form.errors, 'next_finger': upload_count + 1, 'max_images': MAX_IMAGES }) return render(request, 'captureimage.html', { 'next_finger': request.session['upload_count'] + 1, 'max_images': MAX_IMAGES }) </code>
import cv2
import numpy as np
import math
import fingerprint_enhancer  # Ensure this module is available
from django.shortcuts import render
from django.core.files.base import ContentFile
from .forms import HandFingerForm
from .models import ThumbImage
import base64

MAX_IMAGES = 10

def remove_green(img):
    empty_img = np.zeros_like(img)
    RED, GREEN, BLUE = (2, 1, 0)
    reds = img[:, :, RED]
    greens = img[:, :, GREEN]
    blues = img[:, :, BLUE]
    
    # Create a mask for the areas to keep
    tmpMask = (greens < 35) | (reds > greens) | (blues > greens)
    img[tmpMask == 0] = (0, 0, 0)  # Remove background from original picture
    empty_img[tmpMask] = (255, 255, 255)  # Mask with finger in white
    return img, empty_img

def detect_nail(gray_mask_finger):
    # Find contours in the mask image
    contours, _ = cv2.findContours(gray_mask_finger, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    for contour in contours:
        # Only consider large enough contours as nails
        if cv2.contourArea(contour) > 100:  # Adjust this threshold as needed
            x, y, w, h = cv2.boundingRect(contour)
            # Draw a rectangle around the detected nail
            cv2.rectangle(gray_mask_finger, (x, y), (x + w, y + h), (255, 0, 0), 2)  # Blue rectangle

def process_fingerprint(image):
    clip_hist_percent = 25

    # Convert to grayscale
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # Calculate grayscale histogram
    hist = cv2.calcHist([gray], [0], None, [256], [0, 256])
    hist_size = len(hist)

    # Calculate cumulative distribution from the histogram
    accumulator = []
    accumulator.append(float(hist[0]))
    for index in range(1, hist_size):
        accumulator.append(accumulator[index - 1] + float(hist[index]))

    # Locate points to clip
    maximum = accumulator[-1]
    clip_hist_percent *= (maximum / 100.0)
    clip_hist_percent /= 2.0

    # Locate left cut
    minimum_gray = 0
    while accumulator[minimum_gray] < clip_hist_percent:
        minimum_gray += 1

    # Locate right cut
    maximum_gray = hist_size - 1
    while accumulator[maximum_gray] >= (maximum - clip_hist_percent):
        maximum_gray -= 1

    # Calculate alpha and beta values
    alpha = 255 / (maximum_gray - minimum_gray)
    beta = -minimum_gray * alpha

    auto_result = cv2.convertScaleAbs(image, alpha=alpha, beta=beta)

    gray = cv2.cvtColor(auto_result, cv2.COLOR_BGR2GRAY)

    # Compute gamma
    mid = 0.5
    mean = np.mean(gray)
    gamma = math.log(mid * 255) / math.log(mean)
    
    # Apply gamma correction
    img_gamma = np.power(auto_result, gamma).clip(0, 255).astype(np.uint8)
    g1 = cv2.cvtColor(img_gamma, cv2.COLOR_BGR2GRAY)

    # Adaptive thresholding
    thresh2 = cv2.adaptiveThreshold(g1, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                    cv2.THRESH_BINARY, 199, 3)

    # Morphological operations
    blur = ((3, 3), 1)
    erode_ = (5, 5)
    dilate_ = (3, 3)
    dilate = cv2.dilate(cv2.erode(cv2.GaussianBlur(thresh2 / 255, blur[0], blur[1]),
                                    np.ones(erode_)), np.ones(dilate_)) * 255

    # Enhance fingerprint
    out = fingerprint_enhancer.enhance_Fingerprint(dilate)
    
    return out

def upload_image(request):
    if 'upload_count' not in request.session:
        request.session['upload_count'] = 0

    upload_count = request.session['upload_count']

    if request.method == 'POST':
        if 'skip' in request.POST:
            request.session['upload_count'] = 0
            return render(request, 'captureimage.html', {
                'message': 'Skipped the remaining uploads.',
                'next_finger': None,
                'max_images': MAX_IMAGES
            })

        finger_number = request.POST.get('finger')
        image_data = request.POST.get('image')

        if not image_data or ';base64,' not in image_data:
            return render(request, 'captureimage.html', {
                'error': 'Invalid image data',
                'next_finger': upload_count + 1,
                'max_images': MAX_IMAGES
            })

        try:
            format, imgstr = image_data.split(';base64,')
        except ValueError:
            return render(request, 'captureimage.html', {
                'error': 'Failed to parse image data',
                'next_finger': upload_count + 1,
                'max_images': MAX_IMAGES
            })

        ext = format.split('/')[-1]
        image_file = ContentFile(base64.b64decode(imgstr), name=f'finger_{finger_number}.{ext}')

        form_data = {'finger': finger_number}
        form_files = {'image': image_file}

        form = HandFingerForm(form_data, form_files)

        if form.is_valid():
            form.save()

            # Load and process the saved image
            saved_image_path = form.instance.image.path
            image = cv2.imread(saved_image_path, 1)  # Load the image
            image = cv2.resize(image, None, fx=0.3, fy=0.3)  # Resize
            image = cv2.GaussianBlur(image, (3, 3), 0)  # Apply Gaussian blur

            # Process fingerprint
            enhanced_image = process_fingerprint(image)

            # Remove green background
            no_green_image, mask_finger = remove_green(enhanced_image)

            # Convert to grayscale
            gray_mask_finger = cv2.cvtColor(mask_finger, cv2.COLOR_BGR2GRAY)

            # Call the function to detect nail
            detect_nail(gray_mask_finger)

            request.session['upload_count'] += 1

            if request.session['upload_count'] < MAX_IMAGES:
                return render(request, 'captureimage.html', {
                    'message': 'Finger image uploaded successfully.',
                    'next_finger': request.session['upload_count'] + 1,
                    'max_images': MAX_IMAGES
                })
            else:
                request.session['upload_count'] = 0
                return render(request, 'captureimage.html', {
                    'message': 'All 10 images uploaded successfully!',
                    'next_finger': None,
                    'max_images': MAX_IMAGES
                })
        else:
            return render(request, 'captureimage.html', {
                'error': 'Invalid form data',
                'details': form.errors,
                'next_finger': upload_count + 1,
                'max_images': MAX_IMAGES
            })

    return render(request, 'captureimage.html', {
        'next_finger': request.session['upload_count'] + 1,
        'max_images': MAX_IMAGES
    })

#frontend

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Capture Finger Image</title>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Roboto', sans-serif;
background-color: #f4f4f9;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container {
background: #ffffff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
max-width: 500px;
width: 100%;
text-align: center;
}
h2 {
margin-bottom: 20px;
color: #333;
}
#instructions {
font-size: 1.1em;
margin-bottom: 20px;
color: #555;
}
#video {
width: 100%;
border-radius: 8px;
margin-bottom: 10px;
border: 2px solid #007bff;
}
#preview {
margin: 10px 0;
}
#capturedImage {
max-width: 100%;
border-radius: 8px;
border: 2px solid #28a745;
}
select {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
margin-bottom: 20px;
font-size: 1em;
}
.button-group {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
margin-top: 20px;
}
button {
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
padding: 10px 15px;
font-size: 1em;
cursor: pointer;
transition: background-color 0.3s;
flex: 1;
margin: 5px;
}
button:hover {
background-color: #0056b3;
}
.skip-btn {
background-color: #dc3545;
}
.skip-btn:hover {
background-color: #c82333;
}
/* Responsive styles */
@media (max-width: 600px) {
.button-group {
flex-direction: column;
}
button {
margin: 5px 0;
}
}
</style>
</head>
<body>
<div class="container">
<h2>Capture Finger Image</h2>
<div id="instructions">
Please select a finger and place it in front of the camera with good lighting for a clear image.
</div>
<!-- Display Success or Error Message -->
{% if message %}
<p style="color:green;">{{ message }}</p>
{% elif error %}
<p style="color:red;">{{ error }}</p>
{% endif %}
<div class="video-container">
<!-- Video stream -->
<video id="video" autoplay></video>
<!-- Preview for captured image -->
<div id="preview">
<p>Captured Image:</p>
<img id="capturedImage" src="" alt="No image captured yet">
</div>
</div>
<!-- Dropdown for selecting finger -->
<form id="fingerForm">
<select id="fingerSelect" name="finger">
<option value="">Select Finger</option>
<option value="Right Thumb">Right Thumb</option>
<option value="Left Thumb">Left Thumb</option>
<option value="Right Index">Right Index</option>
<option value="Left Index">Left Index</option>
<option value="Right Middle">Right Middle</option>
<option value="Left Middle">Left Middle</option>
<option value="Right Ring">Right Ring</option>
<option value="Left Ring">Left Ring</option>
<option value="Right Pinky">Right Pinky</option>
<option value="Left Pinky">Left Pinky</option>
</select>
</form>
<div class="button-group">
<button id="snap">Capture Finger Image</button>
<!-- Image Upload Form -->
<form id="imageForm" action="{% url 'upload_image' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<input type="hidden" name="image" id="imageInput">
<button type="submit" id="uploadButton" disabled>Upload Finger Image</button>
</form>
<!-- Skip Button -->
<form action="{% url 'upload_image' %}" method="POST">
{% csrf_token %}
<button type="submit" class="skip-btn" name="skip" value="true">Skip Remaining</button>
</form>
</div>
</div>
<script>
const video = document.getElementById('video');
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const snap = document.getElementById('snap');
const imageInput = document.getElementById('imageInput');
const capturedImage = document.getElementById('capturedImage');
const uploadButton = document.getElementById('uploadButton');
const fingerSelect = document.getElementById('fingerSelect');
// Access the camera with higher resolution for better detail
navigator.mediaDevices.getUserMedia({ video: { width: 1280, height: 720 } })
.then((stream) => {
video.srcObject = stream;
})
.catch((error) => {
console.error("Error accessing camera: ", error);
});
// Capture image on button click
snap.addEventListener('click', () => {
// Check if a finger is selected
if (fingerSelect.value === "") {
alert("Please select a finger before capturing the image.");
return;
}
// Set canvas size to match the video feed
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
// Apply a sharpness filter to enhance the fingerprint details
context.filter = 'contrast(1.5) brightness(1.2)'; // Adjust contrast and brightness for clarity
context.drawImage(video, 0, 0, canvas.width, canvas.height);
// Convert the canvas image to base64
const dataURL = canvas.toDataURL('image/png');
imageInput.value = dataURL; // Set base64 image in hidden input
// Display the captured image in the img tag
capturedImage.src = dataURL;
// Set the selected finger in the form data
const fingerInput = document.createElement('input');
fingerInput.type = 'hidden';
fingerInput.name = 'finger';
fingerInput.value = fingerSelect.value;
document.getElementById('imageForm').appendChild(fingerInput);
// Enable the upload button
uploadButton.disabled = false;
});
// Enable form submission when a finger is selected
fingerSelect.addEventListener('change', () => {
if (fingerSelect.value !== "") {
uploadButton.disabled = true; // Reset button state
}
});
</script>
</body>
</html>
</code>
<code><!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Capture Finger Image</title> <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet"> <style> body { font-family: 'Roboto', sans-serif; background-color: #f4f4f9; margin: 0; padding: 0; display: flex; justify-content: center; align-items: center; height: 100vh; } .container { background: #ffffff; padding: 20px; border-radius: 8px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); max-width: 500px; width: 100%; text-align: center; } h2 { margin-bottom: 20px; color: #333; } #instructions { font-size: 1.1em; margin-bottom: 20px; color: #555; } #video { width: 100%; border-radius: 8px; margin-bottom: 10px; border: 2px solid #007bff; } #preview { margin: 10px 0; } #capturedImage { max-width: 100%; border-radius: 8px; border: 2px solid #28a745; } select { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; margin-bottom: 20px; font-size: 1em; } .button-group { display: flex; justify-content: space-between; flex-wrap: wrap; margin-top: 20px; } button { background-color: #007bff; color: white; border: none; border-radius: 4px; padding: 10px 15px; font-size: 1em; cursor: pointer; transition: background-color 0.3s; flex: 1; margin: 5px; } button:hover { background-color: #0056b3; } .skip-btn { background-color: #dc3545; } .skip-btn:hover { background-color: #c82333; } /* Responsive styles */ @media (max-width: 600px) { .button-group { flex-direction: column; } button { margin: 5px 0; } } </style> </head> <body> <div class="container"> <h2>Capture Finger Image</h2> <div id="instructions"> Please select a finger and place it in front of the camera with good lighting for a clear image. </div> <!-- Display Success or Error Message --> {% if message %} <p style="color:green;">{{ message }}</p> {% elif error %} <p style="color:red;">{{ error }}</p> {% endif %} <div class="video-container"> <!-- Video stream --> <video id="video" autoplay></video> <!-- Preview for captured image --> <div id="preview"> <p>Captured Image:</p> <img id="capturedImage" src="" alt="No image captured yet"> </div> </div> <!-- Dropdown for selecting finger --> <form id="fingerForm"> <select id="fingerSelect" name="finger"> <option value="">Select Finger</option> <option value="Right Thumb">Right Thumb</option> <option value="Left Thumb">Left Thumb</option> <option value="Right Index">Right Index</option> <option value="Left Index">Left Index</option> <option value="Right Middle">Right Middle</option> <option value="Left Middle">Left Middle</option> <option value="Right Ring">Right Ring</option> <option value="Left Ring">Left Ring</option> <option value="Right Pinky">Right Pinky</option> <option value="Left Pinky">Left Pinky</option> </select> </form> <div class="button-group"> <button id="snap">Capture Finger Image</button> <!-- Image Upload Form --> <form id="imageForm" action="{% url 'upload_image' %}" method="POST" enctype="multipart/form-data"> {% csrf_token %} <input type="hidden" name="image" id="imageInput"> <button type="submit" id="uploadButton" disabled>Upload Finger Image</button> </form> <!-- Skip Button --> <form action="{% url 'upload_image' %}" method="POST"> {% csrf_token %} <button type="submit" class="skip-btn" name="skip" value="true">Skip Remaining</button> </form> </div> </div> <script> const video = document.getElementById('video'); const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); const snap = document.getElementById('snap'); const imageInput = document.getElementById('imageInput'); const capturedImage = document.getElementById('capturedImage'); const uploadButton = document.getElementById('uploadButton'); const fingerSelect = document.getElementById('fingerSelect'); // Access the camera with higher resolution for better detail navigator.mediaDevices.getUserMedia({ video: { width: 1280, height: 720 } }) .then((stream) => { video.srcObject = stream; }) .catch((error) => { console.error("Error accessing camera: ", error); }); // Capture image on button click snap.addEventListener('click', () => { // Check if a finger is selected if (fingerSelect.value === "") { alert("Please select a finger before capturing the image."); return; } // Set canvas size to match the video feed canvas.width = video.videoWidth; canvas.height = video.videoHeight; // Apply a sharpness filter to enhance the fingerprint details context.filter = 'contrast(1.5) brightness(1.2)'; // Adjust contrast and brightness for clarity context.drawImage(video, 0, 0, canvas.width, canvas.height); // Convert the canvas image to base64 const dataURL = canvas.toDataURL('image/png'); imageInput.value = dataURL; // Set base64 image in hidden input // Display the captured image in the img tag capturedImage.src = dataURL; // Set the selected finger in the form data const fingerInput = document.createElement('input'); fingerInput.type = 'hidden'; fingerInput.name = 'finger'; fingerInput.value = fingerSelect.value; document.getElementById('imageForm').appendChild(fingerInput); // Enable the upload button uploadButton.disabled = false; }); // Enable form submission when a finger is selected fingerSelect.addEventListener('change', () => { if (fingerSelect.value !== "") { uploadButton.disabled = true; // Reset button state } }); </script> </body> </html> </code>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Capture Finger Image</title>
  <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">
  <style>
    body {
      font-family: 'Roboto', sans-serif;
      background-color: #f4f4f9;
      margin: 0;
      padding: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
    }

    .container {
      background: #ffffff;
      padding: 20px;
      border-radius: 8px;
      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
      max-width: 500px;
      width: 100%;
      text-align: center;
    }

    h2 {
      margin-bottom: 20px;
      color: #333;
    }

    #instructions {
      font-size: 1.1em;
      margin-bottom: 20px;
      color: #555;
    }

    #video {
      width: 100%;
      border-radius: 8px;
      margin-bottom: 10px;
      border: 2px solid #007bff;
    }

    #preview {
      margin: 10px 0;
    }

    #capturedImage {
      max-width: 100%;
      border-radius: 8px;
      border: 2px solid #28a745;
    }

    select {
      width: 100%;
      padding: 10px;
      border: 1px solid #ddd;
      border-radius: 4px;
      margin-bottom: 20px;
      font-size: 1em;
    }

    .button-group {
      display: flex;
      justify-content: space-between;
      flex-wrap: wrap;
      margin-top: 20px;
    }

    button {
      background-color: #007bff;
      color: white;
      border: none;
      border-radius: 4px;
      padding: 10px 15px;
      font-size: 1em;
      cursor: pointer;
      transition: background-color 0.3s;
      flex: 1;
      margin: 5px;
    }

    button:hover {
      background-color: #0056b3;
    }

    .skip-btn {
      background-color: #dc3545;
    }

    .skip-btn:hover {
      background-color: #c82333;
    }

    /* Responsive styles */
    @media (max-width: 600px) {
      .button-group {
        flex-direction: column;
      }

      button {
        margin: 5px 0;
      }
    }
  </style>
</head>
<body>
  <div class="container">
    <h2>Capture Finger Image</h2>
    
    <div id="instructions">
      Please select a finger and place it in front of the camera with good lighting for a clear image.
    </div>
    
    <!-- Display Success or Error Message -->
    {% if message %}
      <p style="color:green;">{{ message }}</p>
    {% elif error %}
      <p style="color:red;">{{ error }}</p>
    {% endif %}
    
    <div class="video-container">
      <!-- Video stream -->
      <video id="video" autoplay></video>
      
      <!-- Preview for captured image -->
      <div id="preview">
        <p>Captured Image:</p>
        <img id="capturedImage" src="" alt="No image captured yet">
      </div>
    </div>
    
    <!-- Dropdown for selecting finger -->
    <form id="fingerForm">
      <select id="fingerSelect" name="finger">
        <option value="">Select Finger</option>
        <option value="Right Thumb">Right Thumb</option>
        <option value="Left Thumb">Left Thumb</option>
        <option value="Right Index">Right Index</option>
        <option value="Left Index">Left Index</option>
        <option value="Right Middle">Right Middle</option>
        <option value="Left Middle">Left Middle</option>
        <option value="Right Ring">Right Ring</option>
        <option value="Left Ring">Left Ring</option>
        <option value="Right Pinky">Right Pinky</option>
        <option value="Left Pinky">Left Pinky</option>
      </select>
    </form>

    <div class="button-group">
      <button id="snap">Capture Finger Image</button>

      <!-- Image Upload Form -->
      <form id="imageForm" action="{% url 'upload_image' %}" method="POST" enctype="multipart/form-data">
        {% csrf_token %}
        <input type="hidden" name="image" id="imageInput">
        <button type="submit" id="uploadButton" disabled>Upload Finger Image</button>
      </form>
      
      <!-- Skip Button -->
      <form action="{% url 'upload_image' %}" method="POST">
        {% csrf_token %}
        <button type="submit" class="skip-btn" name="skip" value="true">Skip Remaining</button>
      </form>
    </div>
  </div>

  <script>
    const video = document.getElementById('video');
    const canvas = document.createElement('canvas');
    const context = canvas.getContext('2d');
    const snap = document.getElementById('snap');
    const imageInput = document.getElementById('imageInput');
    const capturedImage = document.getElementById('capturedImage');
    const uploadButton = document.getElementById('uploadButton');
    const fingerSelect = document.getElementById('fingerSelect');

    // Access the camera with higher resolution for better detail
    navigator.mediaDevices.getUserMedia({ video: { width: 1280, height: 720 } })
      .then((stream) => {
        video.srcObject = stream;
      })
      .catch((error) => {
        console.error("Error accessing camera: ", error);
      });

    // Capture image on button click
    snap.addEventListener('click', () => {
      // Check if a finger is selected
      if (fingerSelect.value === "") {
        alert("Please select a finger before capturing the image.");
        return;
      }

      // Set canvas size to match the video feed
      canvas.width = video.videoWidth;
      canvas.height = video.videoHeight;

      // Apply a sharpness filter to enhance the fingerprint details
      context.filter = 'contrast(1.5) brightness(1.2)'; // Adjust contrast and brightness for clarity
      context.drawImage(video, 0, 0, canvas.width, canvas.height);

      // Convert the canvas image to base64
      const dataURL = canvas.toDataURL('image/png');
      imageInput.value = dataURL; // Set base64 image in hidden input

      // Display the captured image in the img tag
      capturedImage.src = dataURL;

      // Set the selected finger in the form data
      const fingerInput = document.createElement('input');
      fingerInput.type = 'hidden';
      fingerInput.name = 'finger';
      fingerInput.value = fingerSelect.value;
      document.getElementById('imageForm').appendChild(fingerInput);

      // Enable the upload button
      uploadButton.disabled = false;
    });

    // Enable form submission when a finger is selected
    fingerSelect.addEventListener('change', () => {
      if (fingerSelect.value !== "") {
        uploadButton.disabled = true; // Reset button state
      }
    });
  </script>
</body>
</html>

#models.py

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>from django.db import models
class ThumbImage(models.Model):
FINGER_CHOICES = [
('Right Thumb', 'Right Thumb'),
('Left Thumb', 'Left Thumb'),
('Right Index', 'Right Index'),
('Left Index', 'Left Index'),
('Right Middle', 'Right Middle'),
('Left Middle', 'Left Middle'),
('Right Ring', 'Right Ring'),
('Left Ring', 'Left Ring'),
('Right Pinky', 'Right Pinky'),
('Left Pinky', 'Left Pinky'),
]
finger = models.CharField(max_length=50, choices=FINGER_CHOICES)
image = models.ImageField(upload_to='finger_images/')
def __str__(self):
return f"{self.finger} image"
</code>
<code>from django.db import models class ThumbImage(models.Model): FINGER_CHOICES = [ ('Right Thumb', 'Right Thumb'), ('Left Thumb', 'Left Thumb'), ('Right Index', 'Right Index'), ('Left Index', 'Left Index'), ('Right Middle', 'Right Middle'), ('Left Middle', 'Left Middle'), ('Right Ring', 'Right Ring'), ('Left Ring', 'Left Ring'), ('Right Pinky', 'Right Pinky'), ('Left Pinky', 'Left Pinky'), ] finger = models.CharField(max_length=50, choices=FINGER_CHOICES) image = models.ImageField(upload_to='finger_images/') def __str__(self): return f"{self.finger} image" </code>
from django.db import models

class ThumbImage(models.Model):
    FINGER_CHOICES = [
        ('Right Thumb', 'Right Thumb'),
        ('Left Thumb', 'Left Thumb'),
        ('Right Index', 'Right Index'),
        ('Left Index', 'Left Index'),
        ('Right Middle', 'Right Middle'),
        ('Left Middle', 'Left Middle'),
        ('Right Ring', 'Right Ring'),
        ('Left Ring', 'Left Ring'),
        ('Right Pinky', 'Right Pinky'),
        ('Left Pinky', 'Left Pinky'),
    ]
    finger = models.CharField(max_length=50, choices=FINGER_CHOICES)
    image = models.ImageField(upload_to='finger_images/')

    def __str__(self):
        return f"{self.finger} image"

I’m currently working on a project that focuses on enhancing fingerprint images using OpenCV. I’ve been implementing various techniques, including converting the images to grayscale, applying histogram equalization, performing gamma correction, using adaptive thresholding, and carrying out morphological operations.

Initially, these steps seemed to improve the contrast and clarity of the images. However, I’ve encountered a problem: the ridge patterns in the fingerprints appear blurred instead of sharp. I expected to see clear, well-defined ridges, but the final results are lacking in clarity.

I would love to hear any suggestions or adjustments I can make to improve the ridge clarity in my fingerprint images. Any advice would be greatly appreciated!

New contributor

updeshkumar pal is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

3

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật