2013-05-16 16 views
7

Esiste una soluzione per accedere ai pixel lungo la curva/il percorso? possiamo usare LineIterator per farloAccesso ai pixel lungo la curva/percorso usando opencv

+1

possibile duplicato di [OpenCV - Accesso al pixel lungo la curva/percorso] (http://stackoverflow.com/questions/5078387/opencv-access-to-pixels-along-the-curve-path) –

+0

da dove prendi la curva/il percorso? O che tipo di percorsi permetti? Polinomi? Spline? – Micka

risposta

4

Ok, ecco un modo per accedere ai pixel lungo una curva collegata che può essere parametrizzata. Ci potrebbero essere modi più efficienti, ma questo è abbastanza semplice: basta campionare la curva in intervalli di parametri in modo da non accedere due volte a un pixel e non saltare un pixel:

Ho preso una funzione parametrica da wikipedia come campione: http://en.wikipedia.org/wiki/Parametric_equation#Some_sophisticated_functions

enter image description here

int main() 
{ 
cv::Mat blank = cv::Mat::zeros(512,512,CV_8U); 

// parametric function: 
// http://en.wikipedia.org/wiki/Parametric_equation#Some_sophisticated_functions 
// k = a/b 
// x = (a-b)*cos(t) + b*cos(t((a/b)-1)) 
// y = (a-b)*sin(t) - b*sin(t((a/b)-1)) 

float k = 0.5f; 
float a = 70.0f; 
float b = a/k; 

// translate the curve somewhere 
float centerX = 256; 
float centerY = 256; 

// you will check whether the pixel position has moved since the last active pixel, so you have to remember the last one: 
int oldpX,oldpY; 
// compute the parametric function's value for param t = 0 
oldpX = (a-b)*cos(0) + b*cos(0*((a/b)-1.0f)) + centerX -1; 
oldpY = (a-b)*sin(0) - b*sin(0*((a/b)-1.0f)) + centerY -1; 

// initial stepsize to parametrize the curve 
float stepsize = 0.01f; 

//counting variables for analyzation 
unsigned int nIterations = 0; 
unsigned int activePixel = 0; 

// iterate over whole parameter region 
for(float t = 0; t<4*3.14159265359f; t+= stepsize) 
{ 
    nIterations++; 

    // compute the pixel position for that parameter 
    int pX = (a-b)*cos(t) + b*cos(t*((a/b)-1.0f)) + centerX; 
    int pY = (a-b)*sin(t) - b*sin(t*((a/b)-1.0f)) + centerY; 

    // only access pixel if we moved to a new pixel: 
    if((pX != oldpX)||(pY != oldpY)) 
    { 
     // if distance to old pixel is too big: stepsize was too big 
     if((abs(oldpX-pX)<=1) && (abs(oldpY-pY)<=1)) 
     { 
      //--------------------------------------------------------------- 
      // here you can access the pixel, it will be accessed only once for that curve position! 
      blank.at<unsigned char>((pY),(pX)) = blank.at<unsigned char>((pY),(pX))+1; 
      //--------------------------------------------------------------- 

      // update last position 
      oldpX = pX; 
      oldpY = pY; 

      activePixel++; // count number of pixel on the contour 
     } 
     else 
     { 
      // adjust/decrease stepsize here 
      t -= stepsize; 
      stepsize /= 2.0f; 

      //TODO: choose smarter stepsize updates 
     } 
    } 
    else 
    { 
     // you could adjust/increase the stepsize here 
     stepsize += stepsize/2.0f; 

     //TODO: prevent stepsize from becoming 0.0f !! 
     //TODO: choose smarter stepsize updates 
    } 

} 
std::cout << "nIterations: " << nIterations << " for activePixel: " << activePixel << std::endl; 

cv::imwrite("accessedOnce.png", blank>0); 
cv::imwrite("accessedMulti.png", blank>1); 

cv::waitKey(-1); 
return 0; 
} 

dare questi risultati:

pixel accede volta:

enter image description here

pixel letta più volte:

enter image description here

uscita del terminale: nIterations: 1240 for activePixel: 1065

+0

possiamo usare il mouse per spostare la curva usando opencv? – AHF

+0

@AHF cosa intendi spostando la curva? openCV ha alcune interfacce per utilizzare gli input del mouse. Ma i miei algoritmi servono per "accedere" (che significa elaborazione automatica di) a ciascun pixel colpito da una curva parametrizzabile (f (t)). – Micka

+0

come lo sto qui http://stackoverflow.com/questions/23641208/how-to-draw-curve-on-control-points-using-opencv ho bisogno di disegnare le tre curve per RGB e spostare la loro curva, tutto funziona bene ma disegnare la curva per muoverti con il mouse crea problemi per me dato che non ho trovato molti buoni esempi su internet – AHF

4

Io non credo che ci sia alcuna funzione built-in per questo. È necessario prima definire la linea/curva in una struttura cv::Mat e poi proseguire da lì. Lasciatemi spiegare con un esempio.

  1. si dispone di un'immagine, cv::Mat input_image e si utilizza un cv::HoughLinesDetector per rilevare le linee nell'immagine che vengono memorizzati in cv::Mat hough_lines.
  2. Sarà quindi necessario scorrere hough_lines e popolare cv::Mat hough_Mat(cv::Size(input_image.size())) (che dovrebbe essere convertito in un'immagine BGR se si desidera mostrare le vostre linee vivacemente contro i dati originali.
  3. Poi, semplicemente operare attraverso hough_Mat per i quali pixel sono al di sopra zero e poi basta accedere alla stessa posizione in input_image.

Sebbene questo esempio è un semplice utilizzando Hough Transform, si può utilizzare qualsiasi altra curva, fino a quando si dispone di dati della curva WRT l'immagine originale.

HTH

Problemi correlati