2013-05-16 13 views
7

Czy istnieje rozwiązanie umożliwiające dostęp do pikseli wzdłuż krzywej/ścieżki? czy możemy użyć LineIterator, aby to zrobić?Dostęp do pikseli wzdłuż krzywej/ścieżki przy użyciu opencv

+1

możliwe duplikat [OpenCV - dostęp do pikseli wzdłuż krzywej/ścieżka] (http://stackoverflow.com/questions/5078387/opencv-access-to-pixels-along- the-curve-path) –

+0

skąd otrzymujesz krzywą/ścieżkę? Albo na jakie patenty pozwalasz? Wielomiany? Splines? – Micka

Odpowiedz

4

OK, oto sposób dostępu do pikseli wzdłuż połączonej krzywej, którą można parametryzować. Mogą być bardziej efektywne sposoby, ale ten jest dość prosty: wystarczy wypróbować krzywą w krokach parametrów, aby nie uzyskać dostępu do piksela dwa razy i nie pomijać piksela:

Zrobiłem funkcję parametryczną od wikipedia jako próbka: 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; 
} 

podając te wyniki:

pikseli obejrzano raz:

enter image description here

pikseli dostępny więcej niż jeden raz:

enter image description here

zacisków wyjściowych: nIterations: 1240 for activePixel: 1065

+0

Czy możemy użyć myszy do przesunięcia krzywej za pomocą opencv? – AHF

+0

@AHF co masz na myśli przesuwając krzywą? openCV ma pewien interfejs do korzystania z wejść myszy. Ale moje algorytmy to "dostęp" (czyli automatyczne przetwarzanie) każdego piksela trafionego przez parametryzowalną krzywą (f (t)). – Micka

+0

jak i stan tutaj http://stackoverflow.com/questions/23641208/how-to-draw-curve-on-control-points-using-opencv Muszę narysować trzy krzywej dla RGB i przenieść ich krzywej, co wszystko działa dobrze, ale rysowanie krzywej, aby poruszać się za pomocą myszy, stwarza dla mnie problem, ponieważ nie dostałem wielu dobrych przykładów w Internecie – AHF

4

nie sądzę istnieje funkcja wbudowana w tej sprawie. Najpierw musisz zdefiniować linię/krzywą w strukturze cv::Mat, a następnie kontynuować. Pozwól mi wyjaśnić na przykładzie.

  1. Masz zdjęcie, cv::Mat input_image i użyć cv::HoughLinesDetector do wykrywania linii w obrazie, które są przechowywane w cv::Mat hough_lines.
  2. Następnie trzeba wykonać iterację hough_lines i wypełnić cv::Mat hough_Mat(cv::Size(input_image.size())) (który powinien zostać przekształcony w BGR obrazu, jeśli chcesz pokazać swoje linie jasno przeciwko oryginalnych danych.
  3. Następnie, po prostu iterację hough_Mat dla których piksele są powyżej zero, a potem po prostu dostęp do tej samej lokalizacji w input_image.

Chociaż ten przykład jest prosta przy użyciu Hough Transform, można go używać w żadnej innej krzywej, tak długo, jak masz dane krzywa jest wrt oryginalny obraz.

HTH

Powiązane problemy