DIP project 1 —— Fingerprint image processing

1 Task Introduction

Fingerprint image processing is an important part of fingerprint
recognition. A fingerprint image usually contains ridge and valley. The
ridge is darker and the valley is brighter. Please use the image processing
method to extract the ridges in the fingerprint image and output a mask.
However, there is a high-resolution fingerprint image acquisition device
that randomly applies a noise during the image acquisition due to the
device itself. You are required to first eliminate this noise through the
knowledge you have learned in class, and then extract the ridge.
在这里插入图片描述

The id of images I handled are 17, 18, 19, 20, they are listed as follows:

  • image 17
    17.bmp-76.1kB

  • image 18
    18.bmp-76.1kB

  • image 19
    19.bmp-76.1kB

  • image 20
    20.bmp-76.1kB

There are two target results I have to get, which are denoised image and ridge mask image of source image.

2 Methods

There are three steps im my method :

  • step1: blur image
  • step2: binarize image
  • step3: remove holes in image

2.1 blur noise

The fisrt step is to think how to blur the source images with noise. We all know that the method you choose to remove noise depends on the kind of noise. According to my dip experience, I analysised the kind of noise of those four images, they are listed as follows:

  • image 17: salt and papper noise
  • iamge 18: pepper noise
  • image 19: salt noise
  • image 20: gaussian noise

The first three images blured easily, but the last image seemed not so easy. After I do gaussian blue and get mask of the last image, I got the this image:

20_ridge_mask.bmp-76.1kB

The last image has two kind of noises, which are gaussian noise and salt-papper noise.

After I blured all images, they are show as follows:

  • 17 denoised image
    17_denoised.bmp-76.1kB
  • 18 denoised image
    18_denoised.bmp-76.1kB
  • 19 denoised image
    19_denoised.bmp-76.1kB
  • 20 denoised image
    20_denoised.bmp-76.1kB

2.2 binarize image

Before we want to get the ridge mask image, we have to binarize images with appropriate threshold. By ajusting threshold parameter, I got the following binarized images:

  • 17 binary image with threshold value 120
    17_binary.bmp-76.1kB
  • 18 binary image with threshold value 50
    18_binary.bmp-76.1kB
  • 19 binary image with threshold value 150
    19_binary.bmp-76.1kB
  • 20 binary image with threshold value 140
    20_binary.bmp-76.1kB

2.3 remove holes

We noticed that there are some tiny white holes in ridges or black holes between ridges. The method I use to remove these two kind of holes is:

  • stpe1: find all contours of connected area in image
  • step2: get tiny contours
  • step3: fill tiny contours which has less than 20 points with black for removing white holes in ridges
  • step4: get tiny contours again
  • step5: fill tiny contours which has less than 30 points with white for removing black holes between ridges

The final ridge mask image I get are as follows:

  • 17 ridge mask image
    17_ridge_mask.bmp-76.1kB
  • 18 ridge mask image
    18_ridge_mask.bmp-76.1kB
  • 19 ridge mask image
    19_ridge_mask.bmp-76.1kB
  • 20 ridge mask image
    20_ridge_mask.bmp-76.1kB

3 cpp code

#include <iostream>
#include <opencv2/opencv.hpp>


using namespace std;
using namespace cv;


// remove contours which has less than cmax points
void RemoveSizeContours(vector<vector<Point>> &contours, int cmax = 20, int cmin = 1)
{
    vector<vector<Point>>::const_iterator itc = contours.begin();
    while (itc != contours.end())
    {
        if ((itc->size()) < cmin || (itc->size()) > cmax)
        {
            itc = contours.erase(itc);
        }
        else ++itc;
    }
}


void HandleImages(string save_path, int id, const cv::Mat &src_img, double thresh)
{
    imshow("source image" + to_string(id), src_img);
    Mat blur_img, bin_img, mask_img;
    if (id <= 3)
    {
        medianBlur(src_img, blur_img, 3);
    }
    else if (id == 4)
    {
        medianBlur(src_img, blur_img, 3);

        GaussianBlur(blur_img, blur_img, Size(5, 5), 0.4);
    }
    else
    {
        cout << "image is is out of range\n";
    }

    imwrite(save_path + "/result/" + to_string(id + 16) + "_denoised" + ".bmp", blur_img);
//    imshow("blured image" + to_string(id), blur_img);
    threshold(blur_img, bin_img, thresh, 255, cv::THRESH_BINARY);
    imwrite(save_path + "/result/" + to_string(id + 16) + "_binary" + ".bmp", bin_img);
//    imshow("binary image"+to_string(id), bin_img);

    //remove white holes in ridges
    vector<vector<Point>> contours;
    findContours(bin_img, contours, cv::RETR_CCOMP, cv::CHAIN_APPROX_NONE, Point(0, 0));
//    cout << contours.size() << endl;
    RemoveSizeContours(contours);
    mask_img = bin_img.clone();
    drawContours(mask_img, contours, -1, Scalar(0), cv::FILLED);   // -1 means draw all contours

    //remove black holes between ridges
    findContours(mask_img, contours, cv::RETR_CCOMP, cv::CHAIN_APPROX_NONE, Point(0, 0));
    cout << contours.size() << endl;
    RemoveSizeContours(contours, 30);
    drawContours(mask_img, contours, -1, Scalar(255), cv::FILLED);   // -1 means draw all contours

    imwrite(save_path + "/result/" + to_string(id + 16) + "_ridge_mask" + ".bmp", mask_img);
    imshow("mask image" + to_string(id), mask_img);
}


int main(int argc, char **argv)
{
    if (argc != 2)
    {
        cout << "usage: run_pro1 img_path" << endl;
        return 1;
    }


    //load images
    vector<cv::Mat> imgs;
    for (int i = 17; i <= 20; ++i)
    {
        Mat img = cv::imread(string(argv[1]) + "/" + to_string(i) + ".bmp", IMREAD_GRAYSCALE);
        imgs.push_back(img);
    }


    //processing image one by one
    string save_path(argv[1]);
    HandleImages(save_path, 1, imgs[0], 120);
    HandleImages(save_path, 2, imgs[1], 50);
    HandleImages(save_path, 3, imgs[2], 150);
    HandleImages(save_path, 4, imgs[3], 140);

    waitKey(0);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值