2013-03-30 11 views
6

手のX線画像があります。私は骨を自動的に抽出する必要があります。私は簡単に別のテクニックを使って手を分割することができます。しかし、私は骨を取る必要があり、それらのテクニックを使用することは助けにはならない。骨のいくつかはより明るいので、他の部分はより明るくなります。したがって、しきい値処理を使用すると一部が消滅し、他の部分は明確に上昇しきい値になります。そして私はおそらく私は手の領域だけを閾値にすべきだと思いますか?正方形ではないROIの閾値は可能ですか?他の解決方法、アドバイスがありますか?たぶん、OpenCVのようなライブラリやそのためのものがありますか?どんな助けでも大変です!X線画像から手骨を抽出する

拡張:

Raw ImageExpected Output

                                  RAW画像                                             予想される出力

+0

は確かですこれは処理に関連するのでしょうか? – Strawberry

+0

タグが間違っています。ごめんなさい。 – JuGi

+3

コンピュータビジョンには、卒業生向けのプログラムがあります。 – Jason

答えて

8

一つのアプローチは、セグメント手や指からである可能性があり画像:

enter image description here

そしてちょうど手のシルエットで別の画像を作成する:あなたはそれを少し小さくした画像を侵食することができますシルエットを持ったら

enter image description here

。これは、に使用されている指が得られ手&指画像、から手を引く:

enter image description here

次のコードは、このアプローチを実行する例を示します。

void detect_hand_and_fingers(cv::Mat& src); 
void detect_hand_silhoutte(cv::Mat& src); 

int main(int argc, char* argv[]) 
{ 
    cv::Mat img = cv::imread(argv[1]); 
    if (img.empty()) 
    { 
     std::cout << "!!! imread() failed to open target image" << std::endl; 
     return -1;   
    } 

    // Convert RGB Mat to GRAY 
    cv::Mat gray; 
    cv::cvtColor(img, gray, CV_BGR2GRAY); 
    cv::Mat gray_silhouette = gray.clone(); 

    /* Isolate Hand + Fingers */ 

    detect_hand_and_fingers(gray); 
    cv::imshow("Hand+Fingers", gray); 
    cv::imwrite("hand_fingers.png", gray); 

    /* Isolate Hand Sillhoute and subtract it from the other image (Hand+Fingers) */ 

    detect_hand_silhoutte(gray_silhouette); 
    cv::imshow("Hand", gray_silhouette); 
    cv::imwrite("hand_silhoutte.png", gray_silhouette); 

    /* Subtract Hand Silhoutte from Hand+Fingers so we get only Fingers */ 

    cv::Mat fingers = gray - gray_silhouette; 
    cv::imshow("Fingers", fingers); 
    cv::imwrite("fingers_only.png", fingers); 
    cv::waitKey(0); 

    return 0; 
} 

void detect_hand_and_fingers(cv::Mat& src) 
{   
    cv::Mat kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3,3), cv::Point(1,1)); 
    cv::morphologyEx(src, src, cv::MORPH_ELLIPSE, kernel);  

    int adaptiveMethod = CV_ADAPTIVE_THRESH_GAUSSIAN_C; // CV_ADAPTIVE_THRESH_MEAN_C, CV_ADAPTIVE_THRESH_GAUSSIAN_C 
    cv::adaptiveThreshold(src, src, 255, 
          adaptiveMethod, CV_THRESH_BINARY, 
          9, -5); 

    int dilate_sz = 1; 
    cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, 
             cv::Size(2*dilate_sz, 2*dilate_sz), 
             cv::Point(dilate_sz, dilate_sz)); 
    cv::dilate(src, src, element); 
} 

void detect_hand_silhoutte(cv::Mat& src) 
{ 
    cv::Mat kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(7, 7), cv::Point(3, 3)); 
    cv::morphologyEx(src, src, cv::MORPH_ELLIPSE, kernel);   

    int adaptiveMethod = CV_ADAPTIVE_THRESH_MEAN_C; // CV_ADAPTIVE_THRESH_MEAN_C, CV_ADAPTIVE_THRESH_GAUSSIAN_C 
    cv::adaptiveThreshold(src, src, 255, 
          adaptiveMethod, CV_THRESH_BINARY, 
          251, 5); // 251, 5 

    int erode_sz = 5; 
    cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, 
             cv::Size(2*erode_sz + 1, 2*erode_sz+1), 
             cv::Point(erode_sz, erode_sz)); 
    cv::erode(src, src, element); 

    int dilate_sz = 1; 
    element = cv::getStructuringElement(cv::MORPH_ELLIPSE, 
             cv::Size(2*dilate_sz + 1, 2*dilate_sz+1), 
             cv::Point(dilate_sz, dilate_sz)); 
    cv::dilate(src, src, element); 

    cv::bitwise_not(src, src); 
} 
関連する問題