2012-06-07 4 views
6

Ich bin eine Aufgabe von Bio Informatics nähern, und einige Funktionen aus einigen Zellen Bilder extrahieren müssen.Ausreißer SIFT Key Points in Cell Bild mit OpenCV

Ich habe SIFT-Algorithmus verwendet, um wichtige Punkte innerhalb des Bildes zu extrahieren, wie Sie auf dem Bild sehen können.

enter image description here

Wie Sie auch in dem Bild (rot eingekreist), einige der wichtigsten Punkte sind Ausreisser sehen können und ich will nicht auf sie jede Funktion berechnen.

Ich erhielt das cv::KeyPoint Vektor mit dem folgenden Code:

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

aber ich würde von den vector all diesen wichtigen Punkten verwerfen möchte, die zum Beispiel sagen, haben weniger als 3 wichtigsten Punkte innerhalb eines bestimmten Region of Interest (ROI) zentriert auf sie im Bild.

Daher muss ich die Anzahl der wichtigsten Punkte innerhalb einer bestimmten ROI, eine Funktion implementieren als Eingabe gegeben Rückkehr:

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

Ich habe drei Fragen:

  1. Gibt es eine vorhandene Funktion zu tun sowas ähnliches?
  2. Wenn nicht, können Sie mir helfen, zu verstehen, wie ich es selbst implementieren kann?
  3. Würdest du eine kreisförmige oder rechteckige ROI für diese Aufgabe verwenden und wie würdest du sie in der Eingabe angeben?

Hinweis:

Ich habe vergessen zu präzisieren, dass ich eine effiziente Implementierung für die Funktion haben möchten, dh für jeden Schlüsselpunkt bezüglich der relativen Position aller anderen zu überprüfen, es ist keine gute Lösung wäre (wenn es einen anderen Weg gibt).

+1

Können Sie das Originalbild posten? Ich würde gerne etwas ausprobieren und dann die Ergebnisse zurücksenden, wenn es erfolgreich ist :) – mevatron

+0

@mevatron - http://s18.postimage.org/jayhj4q3d/phase1_image1.jpg hier gehts, ich habe die RGB-Version hochgeladen, wandeln Sie es einfach in Graustufen um, wenn Sie wünschen .... lassen Sie mich wissen, was Sie tun;) – Matteo

+0

Sie können RANSAC verwenden, wenn Sie ein Modell definieren können. RANSAC entscheidet, welche Punkte Inlier (passen Sie das Modell) und Ausreißer (passt nicht zum Modell). Vielleicht kann Ihr Modell so etwas wie 3 Punkte sein, die einen Bereich kleiner als X definieren (es bedeutet, dass sie nah genug sind). Es ist eine Idee. –

Antwort

8

Ich entschied mich, mit der statistischen Route zu gehen, aber das funktioniert möglicherweise nicht, wenn Sie mehrere Zellen im Blick haben.

Meine Lösung ist recht einfach:

  1. Berechnen Sie die keypoint Standorte
  2. Finden Sie den Schwerpunkt der keypoint räumlichen Positionen
  3. Compute der euklidische Abstand aller Punkte auf den Schwerpunkt
  4. Filter original keypoints von distance < mu + 2*sigma

Hier ist das Bild, das ich g et Verwendung dieses Algorithmus (keypoints == grün, Schwerpunkt == rot):

enter image description here

Schließlich, hier ist der Code Beispiel dafür, wie ich es tat:

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

Hoffnung, das hilft!

+0

Eigentlich ist die Lösung, die Sie vorgeschlagen, wirklich ordentlich und unkompliziert !! Wie Sie jedoch bemerkt haben, kann dies zu Problemen führen, wenn mehr als eine Zelle im Bild enthalten ist. In meinem Dataset gibt es einige schlechte Bilder, aber ich versuche es zu bereinigen, indem ich diese Samples verwerfe. Ich bleibe vorerst bei dieser Lösung und bitte um weitere Hilfe! ;) THKS SO VIEL ... – Matteo

+2

Super! Freut mich, dass Sie es nützlich fanden; cooles Problem übrigens :) Ich dachte, wenn Sie mehrere Zellen haben, könnten Sie in der Lage sein, irgendeine Art von Clustering-Operation (K-Nearest Neighbors oder etwas Ähnliches) als Vorverarbeitungsschritt auszuführen und sie separat auf diese Weise zu verarbeiten. – mevatron

+1

Es ist ein Projekt in Bioinformatik, ich muss die Evolution von Zellen klassifizieren, indem ich ihre Morphologie analysiere! Und das ist erst der Anfang;) Auch die k-means Idee scheint wirklich schlau, ich werde es versuchen und wenn Sie interessiert sind, finden Sie einen Weg, um Sie über die Entwicklung des Projekts zu informieren. – Matteo

Verwandte Themen