2013-05-16 3 views
7

Есть ли решение для доступа к пикселям вдоль кривой/пути? мы можем использовать LineIterator для этогоДоступ к пикселям вдоль кривой/пути с использованием opencv

+1

возможно дубликат [OpenCV - Доступ к пикселов вдоль кривой/путь] (HTTP://stackoverflow.com/questions/5078387/opencv-access-to-pixels-along-the-curve-path) –

+0

где вы получаете кривую/путь? Или какие пути вы разрешаете? Многочлены? Сплайны? – Micka

ответ

4

Хорошо, вот способ доступа к пикселю вдоль связанной кривой, которая может быть параметризована. Там могут быть более эффективные способы, но это достаточно просто: просто проведите кривую в параметрах, чтобы вы не дважды обращались к пикселю и не пропускали пиксель:

Я взял параметрическую функцию из википедия в качестве образца: 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; 
} 

дает следующие результаты:

пикселей доступ один раз:

enter image description here

пикселей доступ более чем один раз:

enter image description here

терминал выход: nIterations: 1240 for activePixel: 1065

+0

Можно ли использовать мышь для перемещения кривой с помощью opencv? – AHF

+0

@AHF Что вы подразумеваете под движением кривой? openCV имеет некоторый интерфейс для использования входов мыши. Но мои алгоритмы предназначены для «доступа» (что означает автоматическую обработку) каждого пикселя, который попадает под параметризуемую (f (t)) кривую. – Micka

+0

как я заявляю здесь http://stackoverflow.com/questions/23641208/how-to-draw-curve-on-control-points-using-opencv Мне нужно нарисовать три кривые для RGB и переместить их кривую, все работает отлично, но рисование кривой для перемещения с помощью мыши создает проблему для меня, поскольку у меня не было много хороших примеров в Интернете. – AHF

4

Я не думаю, что есть какие-либо встроенные функции для этого. Сначала вам нужно определить линию/кривую в структуре cv::Mat, а затем перейти оттуда. Позвольте мне объяснить пример.

  1. У вас есть изображение, cv::Mat input_image и вы используете cv::HoughLinesDetector для обнаружения линий в изображении, которые хранятся в cv::Mat hough_lines.
  2. Затем вам нужно будет перебирать hough_lines и заполнить cv::Mat hough_Mat(cv::Size(input_image.size())) (который должен быть преобразован в BGR изображение, если вы хотите, чтобы показать свои линии ярко против исходных данных.
  3. Затем просто перебирать hough_Mat, для которых пикселей выше ноль, а затем просто получить доступ к той же месте в input_image.

Хотя этот пример является простым с помощью преобразования Хока, вы можете использовать его с любой другой кривой, до тех пор, пока у вас есть данные кривой в WRT исходное изображение.

HTH

Смежные вопросы