2013-06-19 2 views
3

Я пытаюсь реализовать в OpenCV алгоритм, чтобы выявить детали палиновой вены. Я основывался на бумаге под названием «A Contactless Biometric System Using Palm Print and Palm Vein Features», которую я нашел в Интернете. Часть, которую меня интересует, - это глава 3.2 Предварительная обработка. Здесь показаны этапы.Улучшение пальмовых вен с помощью OpenCV

Я хотел бы сделать реализацию с использованием OpenCV, но до сих пор я сильно застрял. Особенно они используют фильтр Лапласиана на отклик фильтра нижних частот, чтобы изолировать основные вены, но мой результат становится очень шумным, независимо от параметров, которые я пытаюсь!

Любая помощь была бы принята с благодарностью!

+0

вы могли бы разместить код, который вы имеете для предварительной обработки? Если я правильно понимаю, чтобы найти края, вы должны искать нулевые пересечения в выходе лапласиана (хотя бумага, похоже, делает что-то другое). Кстати, глядя на ладонь моей руки, главная особенность, которая отличает основные линии гребня и вены от всего остального, - это цвет, так что лучше попробовать. – Bull

ответ

7

Хорошо, наконец, я сам разобрался, как это сделать. Вот мой код:

#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/imgproc/imgproc.hpp> 

#define THRESHOLD 150 
#define BRIGHT 0.7 
#define DARK 0.2 

using namespace std; 
using namespace cv; 

int main() 
{ 

    // Read source image in grayscale mode 
    Mat img = imread("roi.png", CV_LOAD_IMAGE_GRAYSCALE); 

    // Apply ??? algorithm from https://stackoverflow.com/a/14874992/2501769 
    Mat enhanced, float_gray, blur, num, den; 
    img.convertTo(float_gray, CV_32F, 1.0/255.0); 
    cv::GaussianBlur(float_gray, blur, Size(0,0), 10); 
    num = float_gray - blur; 
    cv::GaussianBlur(num.mul(num), blur, Size(0,0), 20); 
    cv::pow(blur, 0.5, den); 
    enhanced = num/den; 
    cv::normalize(enhanced, enhanced, 0.0, 255.0, NORM_MINMAX, -1); 
    enhanced.convertTo(enhanced, CV_8UC1); 

    // Low-pass filter 
    Mat gaussian; 
    cv::GaussianBlur(enhanced, gaussian, Size(0,0), 3); 

    // High-pass filter on computed low-pass image 
    Mat laplace; 
    Laplacian(gaussian, laplace, CV_32F, 19); 
    double lapmin, lapmax; 
    minMaxLoc(laplace, &lapmin, &lapmax); 
    double scale = 127/ max(-lapmin, lapmax); 
    laplace.convertTo(laplace, CV_8U, scale, 128); 

    // Thresholding using empirical value of 150 to create a vein mask 
    Mat mask; 
    cv::threshold(laplace, mask, THRESHOLD, 255, CV_THRESH_BINARY); 

    // Clean-up the mask using open morphological operation 
    morphologyEx(mask,mask,cv::MORPH_OPEN, 
     getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5,5))); 

    // Connect the neighboring areas using close morphological operation 
    Mat connected; 
    morphologyEx(mask,mask,cv::MORPH_CLOSE, 
     getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(11,11))); 

    // Blurry the mask for a smoother enhancement 
    cv::GaussianBlur(mask, mask, Size(15,15), 0); 

    // Blurry a little bit the image as well to remove noise 
    cv::GaussianBlur(enhanced, enhanced, Size(3,3), 0); 

    // The mask is used to amplify the veins 
    Mat result(enhanced); 
    ushort new_pixel; 
    double coeff; 
    for(int i=0;i<mask.rows;i++){ 
     for(int j=0;j<mask.cols;j++){ 
      coeff = (1.0-(mask.at<uchar>(i,j)/255.0))*BRIGHT + (1-DARK); 
      new_pixel = coeff * enhanced.at<uchar>(i,j); 
      result.at<uchar>(i,j) = (new_pixel>255) ? 255 : new_pixel; 
     } 
    } 

    // Show results 
    imshow("frame", img); 
    waitKey(); 

    imshow("frame", result); 
    waitKey(); 

    return 0; 
} 

Итак, основные этапы работы приведены здесь. Для некоторых частей я вдохновил себя на код, который я нашел. Это касается первой обработки, которую я применяю, что я нашел here. Также для фильтра верхних частот (лапласиан) я вдохновил себя на код, приведенный в OpenCV 2 Computer Vision Application Programming Cookbook.

Наконец-то я сделал некоторые небольшие улучшения, позволив изменить яркость фона и тьму вены (см. Определение ЯРКОГО и ТЕМНОГО). Я также решил немного размыть маску, чтобы иметь более «естественное» улучшение.


Здесь результаты (результат Источник/Бумага/Мой результат):

The source image The paper result My result

+0

Можете ли вы опубликовать полученные изображения? – joshim5

+0

Рассматривали ли вы использование фильтра LBP? Это создаст изображение, которое является амплитудно-инвариантным (т. Е. Только шаблон, а не контраст/яркость). Учитывая, что вам понадобится только информация о фазе для шага кодирования veincode, это может быть шаг «предварительной очистки». – cjm2671

Смежные вопросы