3

手のひらの静脈パターンの詳細を引き出すアルゴリズムを OpenCV に実装しようとしています。私は、インターネットで見つけた「手のひら印刷と手のひら静脈機能を使用した非接触バイオメトリック システム」という論文に基づいています。私が興味を持っているのは、章3.2 Pre-processingです。関連する手順がそこに示されています。

OpenCV を使用して実装を行いたいのですが、今のところ苦労しています。特に、彼らはローパス フィルターの応答にラプラシアン フィルターを使用して主要な静脈を分離しますが、私の結果は、私が試したパラメーターに関係なく、非常にノイズが多くなります!

どんな助けでも大歓迎です!

4

1 に答える 1

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;
}

したがって、この論文の主な手順は次のとおりです。いくつかの部分については、私が見つけたコードからインスピレーションを得ました。ここで見つけたのは、私が適用した最初の処理の場合です。また、ハイパス フィルター (ラプラシアン) については、OpenCV 2 Computer Vision Application Programming Cookbookに記載されているコードに着想を得ました。

最後に、背景の明るさと静脈の暗さを変更できるようにすることで、いくつかの小さな改善を行いました (BRIGHT と DARK の定義を参照)。また、マスクを少しぼかして、より「自然な」強化を行うことにしました。


ここに結果(ソース/紙の結果/私の結果):

ソース画像 論文結果 私の結果

于 2013-06-25T14:56:27.550 に答える