2013-03-30 10 views
6

Ho l'immagine a raggi X di una mano. Ho bisogno di estrarre le ossa automaticamente. Posso segmentare facilmente una mano usando tecniche diverse. Ma ho bisogno di prendere le ossa e usare quelle tecniche non aiuta. Alcune delle ossa sono più luminose degli oringe, quindi se uso la soglia alcune di esse scompaiono mentre altre diventano più chiare. E penso che forse dovrei stabilire un limite solo per una regione della mano? È possibile limitare la ROI che non è un quadrato? O forse hai altre soluzioni, consigli? Forse ci sono alcune librerie come OpenCV o qualcosa del genere? Qualsiasi aiuto sarebbe molto grande!Estrarre le ossa delle mani dall'immagine a raggi X

estesa:

Raw Image Expected Output

                                  immagine RAW                                             Previsto in uscita

+0

Sei sicuro che questo riguarda l'elaborazione? – Strawberry

+0

Tag errato. Scusate. – JuGi

+3

Ci sono grandi programmi scolastici in computer vision. – Jason

risposta

8

Un approccio potrebbe essere quello di segmento mano e delle dita da l'immagine:

enter image description here

E poi la creazione di un'altra immagine con un solo la silhouette mano:

enter image description here

Una volta che hai la silhouette si può erodere l'immagine per renderlo un po 'più piccola . Questo è usato per sottrarre la mano dalla mano & dita immagine, con conseguente le dita:

enter image description here

Il codice seguente mostra per eseguire questo approccio:

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