2013-03-30 1 views
6

나는 손의 x- 레이 이미지를 가지고 있습니다. 나는 뼈를 자동으로 추출해야한다. 다른 기술을 사용하여 손을 쉽게 분할 할 수 있습니다. 그러나 나는 뼈를 가져야하고 그 기술을 사용하면 도움이되지 않습니다. 뼈의 일부는 더 밝고 오서리입니다. 따라서 임계 값을 사용하면 일부는 사라지고 다른 임계 값은 더 높아집니다. 그리고 저는 아마도 손의 영역만을 임계 값으로해야한다고 생각합니까? 사각형이 아닌 ROI를 임계 값으로 설정할 수 있습니까? 혹시 다른 해결책이나 조언이 있으십니까? 어쩌면 OpenCV 같은 라이브러리가 있을까요? 어떤 도움이라도 아주 좋을 것입니다!엑스레이 이미지에서 손 뼈를 뽑아 내십시오

확장 :

Raw Image Expected Output

                                  RAW 이미지                                             예상 출력

+0

당신이 확실 :

enter image description here

아래 코드는이 방법을 실행하는 방법을 보여줍니다 :이 & 손가락 이미지 손가락, 결과 손에서 손을 빼기 에 사용된다 이것은 처리와 관련이 있다는 말인가? – Strawberry

+0

태그가 잘못되었습니다. 죄송합니다. – JuGi

+3

컴퓨터 비전에는 훌륭한 대학원 프로그램이 있습니다. – Jason

답변

8

한 가지 방법은 세그먼트 손과 손가락에서에 수 이미지 :

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