2012-06-07 15 views
6

के साथ सेल छवि में बाहरी SIFT कुंजी बिंदुओं को छोड़ दें मैं जैव सूचना विज्ञान के कार्य के करीब आ रहा हूं, और कुछ सेल छवियों से कुछ विशेषताओं को निकालने की आवश्यकता है।ओपनसीवी

मैंने चित्र के अंदर मुख्य बिंदु निकालने के लिए SIFT एल्गोरिदम का उपयोग किया, जैसा कि आप चित्र में देख सकते हैं।

enter image description here

आप भी चित्र (लाल रंग में परिक्रमा) में देख सकते हैं, कुछ महत्वपूर्ण बिंदुओं बाहरी कारकों के कारण कर रहे हैं और मैं उन पर कोई सुविधा गणना करने के लिए नहीं करना चाहती।

मैं निम्नलिखित कोड के साथ cv::KeyPoint वेक्टर प्राप्त:

const cv::Mat input = cv::imread("/tmp/image.jpg", 0); //Load as grayscale 

cv::SiftFeatureDetector detector; 
std::vector<cv::KeyPoint> keypoints; 
detector.detect(input, keypoints); 

लेकिन मैं vector उन सभी महत्वपूर्ण बिंदुओं कि, उदाहरण के लिए कहते हैं, एक निश्चित के अंदर कम से कम 3 महत्वपूर्ण बिंदुओं है से निरस्त करने के लिए चाहते हैं छवि में रुचि केंद्रित क्षेत्र (आरओआई)।

int function_returning_number_of_key_points_in_ROI(cv::KeyPoint, ROI); 
    //I have not specified ROI on purpose...check question 3 

मैं तीन प्रश्न हैं::

इसलिए मैं इनपुट के रूप में दिए गए एक निश्चित लागत पर लाभ के अंदर महत्वपूर्ण बिंदुओं की संख्या वाला फ़ंक्शन लागू करने की आवश्यकता

  1. वहाँ क्या कर रही किसी भी मौजूदा समारोह है कुछ समान?
  2. यदि आप मुझे इसे लागू करने के तरीके को समझने में कुछ मदद नहीं दे सकते हैं?
  3. क्या आप इस कार्य के लिए एक परिपत्र, या आयताकार आरओआई का उपयोग करेंगे? और आप इसे इनपुट में कैसे निर्दिष्ट करेंगे?

नोट:

मैं निर्दिष्ट करने के लिए है कि मैं समारोह, यानी सम्मान के साथ अन्य सभी की सापेक्ष स्थिति प्रत्येक प्रमुख मुद्दा के लिए जाँच के लिए एक कुशल कार्यान्वयन पसंद करने के लिए यह एक अच्छा समाधान नहीं होगा होगा (भूल गया अगर ऐसा करने का दूसरा तरीका मौजूद है)।

+1

क्या आप मूल छवि पोस्ट कर सकते हैं? मैं कुछ कोशिश करना चाहता हूं, और फिर सफल होने पर परिणाम वापस पोस्ट करना :) – mevatron

+0

@mevatron - http://s18.postimage.org/jayhj4q3d/phase1_image1.jpg यहां जाएं, मैंने आरजीबी संस्करण अपलोड किया है, अगर आप चाहें तो इसे ग्रेस्केल में कनवर्ट करें .... मुझे बताएं कि आप क्या कर रहे हैं;) – Matteo

+0

यदि आप मॉडल को परिभाषित कर सकते हैं तो आप RANSAC का उपयोग कर सकते हैं। RANSAC तय करेगा कि कौन से अंक इनलाइनर्स (मॉडल फिट करें) और आउटलायर (मॉडल फिट नहीं हैं)। हो सकता है कि आपका मॉडल एक्स से छोटे क्षेत्र को परिभाषित करने वाले 3 बिंदुओं की तरह कुछ हो (इसका मतलब है कि वे काफी करीब हैं)। यह एक विचार है। –

उत्तर

8

मैंने सांख्यिकीय मार्ग के साथ जाने का फैसला किया, लेकिन यदि आपके पास एकाधिक सेल्स देखने हैं तो यह काम नहीं कर सकता है।

मेरे समाधान काफी सीधा है:

  1. कंप्यूट Keypoint स्थानों
  2. Keypoint स्थानिक स्थानों
  3. कंप्यूट केन्द्रक को
  4. फ़िल्टर मूल keypoints सभी बिंदुओं का इयूक्लिडियन दूरी के केन्द्रक का पता लगाएं distance < mu + 2*sigma

यहां छवि है कि मैं जी एट इस कलन विधि का उपयोग (keypoints == हरे, केन्द्रक == लाल):

#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/imgproc/imgproc.hpp> 
#include <opencv2/features2d/features2d.hpp> 

#include <iostream> 
#include <vector> 

using namespace cv; 
using namespace std; 

void distanceFromCentroid(const vector<Point2f>& points, Point2f centroid, vector<double>& distances) 
{ 
    vector<Point2f>::const_iterator point; 
    for(point = points.begin(); point != points.end(); ++point) 
    { 
     double distance = std::sqrt((point->x - centroid.x)*(point->x - centroid.x) + (point->y - centroid.y)*(point->y - centroid.y)); 
     distances.push_back(distance); 
    } 
} 

int main(int argc, char* argv[]) 
{ 
    Mat input = imread("cell.jpg", 0); //Load as grayscale 

    SiftFeatureDetector detector; 
    vector<cv::KeyPoint> keypoints; 
    detector.detect(input, keypoints); 

    vector<Point2f> points; 
    vector<KeyPoint>::iterator keypoint; 
    for(keypoint = keypoints.begin(); keypoint != keypoints.end(); ++keypoint) 
    { 
     points.push_back(keypoint->pt); 
    } 

    Moments m = moments(points, true); 
    Point2f centroid(m.m10/m.m00, m.m01/m.m00); 

    vector<double> distances; 
    distanceFromCentroid(points, centroid, distances); 

    Scalar mu, sigma; 
    meanStdDev(distances, mu, sigma); 

    cout << mu.val[0] << ", " << sigma.val[0] << endl; 

    vector<KeyPoint> filtered; 
    vector<double>::iterator distance; 
    for(size_t i = 0; i < distances.size(); ++i) 
    { 
     if(distances[i] < (mu.val[0] + 2.0*sigma.val[0])) 
     { 
      filtered.push_back(keypoints[i]); 
     } 
    } 

    Mat out = input.clone(); 
    drawKeypoints(input, filtered, out, Scalar(0, 255, 0)); 

    circle(out, centroid, 7, Scalar(0, 0, 255), 1); 

    imshow("kpts", out); 
    waitKey(); 

    imwrite("statFilter.png", out); 

    return 0; 
} 

आशा है कि मदद करता है:

enter image description here

अंत में, यहाँ मैं इसे कैसे किया कोड उदाहरण है!

+0

असल में आपके द्वारा प्रस्तावित समाधान वास्तव में साफ और सीधा है !! हालांकि, जैसा कि आपने देखा है, छवि में सेल से अधिक होने पर इसमें समस्या हो सकती है। मेरे डेटासेट में कुछ खराब छवियां हैं, लेकिन मैं उन नमूनों को छोड़कर इसे साफ़ करने की कोशिश कर रहा हूं। मैं अब इस समाधान के साथ रहूंगा, और मामले में और मदद के लिए पूछूंगा! ;) बहुत कुछ है ... – Matteo

+2

बहुत बढ़िया! खुशी हुई कि यह आपको उपयोगी लगा; रास्ते में ठंडी समस्या :) मैं सोच रहा था कि यदि आपके पास एकाधिक सेल्स हैं तो आप प्री-प्रोसेसिंग चरण के रूप में कुछ प्रकार के क्लस्टरिंग ऑपरेशन (के-नजदीकी पड़ोसियों या कुछ समान) करने में सक्षम हो सकते हैं, और उन्हें अलग तरीके से संसाधित कर सकते हैं। – mevatron

+1

यह जैव सूचना विज्ञान में एक परियोजना है, मुझे अपनी रूपरेखा का विश्लेषण करके कोशिकाओं के विकास को वर्गीकृत करने की आवश्यकता है! और यह केवल शुरुआत है;) के-साधन विचार वास्तव में चालाक लगता है, मैं इसे आज़माउंगा और यदि आप रुचि रखते हैं तो आपको परियोजना के विकास को जानने के लिए कुछ रास्ता मिल जाए। – Matteo