Is there a solution to access to pixels along the curve /path ? can we use LineIterator to do it
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
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
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:
pixel accessed more than once:
terminal output:
nIterations: 1240 for activePixel: 1065
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.
cv::Mat input_image
and you use a cv::HoughLinesDetector
to detect lines in the image which are stored in cv::Mat hough_lines
. 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. 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With