是否有解决方案来访问沿曲线 /path 的像素?我们可以使用 LineIterator 来做吗
问问题
2241 次
3 回答
6
是的,您可以使用该CvLineIterator
方法访问像素。
请参考以下链接,
http://opencv.jp/opencv-2.2_org/c/core_drawing_functions.html
于 2013-12-20T15:31:51.113 回答
4
我认为没有任何内置功能。您需要首先在cv::Mat
结构中定义线/曲线,然后从那里继续。让我用一个例子来解释。
- 您有一个图像,
cv::Mat input_image
并且您使用 acv::HoughLinesDetector
来检测图像中存储在cv::Mat hough_lines
. - 然后,您将需要遍历
hough_lines
并填充cv::Mat hough_Mat(cv::Size(input_image.size()))
(如果您想根据原始数据明亮地显示线条,则应将其转换为 BGR 图像。 - 然后,简单地遍历
hough_Mat
哪些像素高于零,然后访问input_image
.
尽管此示例是使用霍夫变换的简单示例,但您可以将其与任何其他曲线一起使用,只要您有原始图像中的曲线数据即可。
高温高压
于 2013-12-20T16:22:36.257 回答
4
好的,这是一种沿着可以参数化的连接曲线访问像素的方法。可能有更有效的方法,但这个方法非常简单:只需在参数步骤中对曲线进行采样,这样您就不会两次访问一个像素并且不会跳过一个像素:
我以维基百科的参数函数为例: 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;
}
给出这些结果:
像素访问一次:
像素访问不止一次:
终端输出:
nIterations: 1240 for activePixel: 1065
于 2013-12-20T19:24:52.877 回答