7

Is there a solution to access to pixels along the curve /path ? can we use LineIterator to do it

user138957
  • 251
  • 4
  • 19
  • 1
    possible duplicate of [OpenCV - Access to pixels along the curve/path](http://stackoverflow.com/questions/5078387/opencv-access-to-pixels-along-the-curve-path) – Kai Walz Dec 20 '13 at 05:48
  • where do you get the curve/path from? Or what kind of pathes do you allow? Polynomials? Splines? – Micka Dec 20 '13 at 18:02

3 Answers3

6

Yes you can use the CvLineIterator method to access the pixels.

Please refer the following link,

http://opencv.jp/opencv-2.2_org/c/core_drawing_functions.html

4

I don't think there is any built-in function for this. You need to first define the line/curve in a cv::Mat structure and then go on from there. Let me explain with an example.

  1. You have an image, cv::Mat input_image and you use a cv::HoughLinesDetector to detect lines in the image which are stored in cv::Mat hough_lines.
  2. You will then need to iterate through hough_lines and populate cv::Mat hough_Mat(cv::Size(input_image.size())) (which should be converted to a BGR image if you want to show your lines brightly against the original data.
  3. Then, simply iterate through hough_Mat for which pixels are above zero and then just access the same location in input_image.

Though this example is a simple one using Hough Transform, you can use it with any other curve, as long as you have the curve's data wrt the original image.

HTH

scap3y
  • 1,188
  • 10
  • 27
4

Ok, here is a way to access pixel along a connected curve that can be parametrized. There might be more efficient ways, but this one is quite simple: just sample the curve in parametersteps so that you don't access a pixel twice and don't skip a pixel:

I've taken a parametric function from wikipedia as a sample: 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;
}

giving these results:

pixel accessed once:

enter image description here

pixel accessed more than once:

enter image description here

terminal output: nIterations: 1240 for activePixel: 1065

Micka
  • 19,585
  • 4
  • 56
  • 74
  • can we use the the mouse to move the curve using opencv ? – AHF May 14 '14 at 11:11
  • @AHF what do you mean by moving the curve? openCV has some interface to use mouse inputs. But my algorithms is for "accessing" (meaning automatic processing of) each pixel that is hit by a parameterizable (f(t) ) curve. – Micka May 14 '14 at 11:20
  • like i state here http://stackoverflow.com/questions/23641208/how-to-draw-curve-on-control-points-using-opencv i need to draw the three curve for RGB and move their curve , everythings work fine but drawing curve to move with the mouse is creating problem for me as i didnt get much good examples on the internet – AHF May 14 '14 at 11:30
  • sorry, my algorithm is neither for drawing bezier curves, nor about mouse callbacks. I think the easiest solution to your problem would be to use one trackbar for each control point! using freehand mouse movement you would have to limit the movement (only y direction and min/max) which is all done easily with trackbars. alternatively you could use a single trackbar and choose the control point you want to move with another mouse click (and use trackbar to move the chosen point) – Micka May 14 '14 at 12:56
  • i think trackbar will not work in that way like curves result , but anyways thanks – AHF May 14 '14 at 13:10
  • you want to move the control points, right? they are allowed to be moved only in y-direction, so you can use a trackbar to set the y-direction. – Micka May 14 '14 at 13:31
  • yes i want to move the control points , but look at the blue control point , can trackbar act like that ? – AHF May 14 '14 at 13:36
  • sure, settings for the 5 trackbars for the 5 control points of the blue curve would be set to something like this (approximately): A: 5%; B: 65%; C: 80%; D: 78%; E: 50%; – Micka May 14 '14 at 13:45