2013-03-30 4 views
6

Ich habe Röntgenbild einer Hand. Ich muss Knochen automatisch extrahieren. Ich kann eine Hand mit verschiedenen Techniken leicht segmentieren. Aber ich brauche Knochen und diese Techniken helfen nicht. Einige der Knochen sind heller als die Orthes, also wenn ich Schwellwerte verwende, verschwinden einige von ihnen, während andere deutlicher ansteigende Schwelle werden. Und ich denke, vielleicht sollte ich nur eine Region der Hand schwellen lassen? Ist es möglich, einen Schwellen-ROI zu erhalten, der kein Quadrat ist? Hast du vielleicht andere Lösungen, Ratschläge? Vielleicht gibt es einige Bibliotheken wie OpenCV oder etwas dafür? Jede Hilfe wäre sehr gut!Extrahieren Sie Handknochen von Röntgenbild

Extended:

Raw Image Expected Output

                                  Raw Bild                                             Erwartete Ausgabe

+0

Sind Sie sicher, dass das mit der Verarbeitung zu tun hat? – Strawberry

+0

Falscher Tag. Es tut uns leid. – JuGi

+3

Es gibt große grad Schule Programme in Computer Vision. – Jason

Antwort

8

Ein Ansatz zur Segment der Hand und der Finger könnte aus das Bild:

enter image description here

Und dann ein anderes Bild nur mit dem Hand Silhouette zu schaffen:

enter image description here

Sobald Sie die Silhouette haben Sie das Bild erodieren kann es ein wenig kleiner zu machen .

enter image description here

Der folgende Code zeigt auszuführen diesen Ansatz: Dies wird abziehen, um die Hand von der Hand & Finger Bild, was in den Fingern verwendet

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