【问题标题】:Implementation of feature detection algorithm特征检测算法的实现
【发布时间】:2016-01-11 15:21:13
【问题描述】:

我是编程新手,想知道如何开始在 C++ 中实现以下算法,

给定一个二值图像,其中强度为 255 的像素显示边缘,强度为 0 的像素显示背景,在图像中找到比n 像素长的线段。 t 是一个计数器,显示没有找到一行的迭代次数,tm 是退出程序前允许的最大迭代次数。

  1. t=0.
  2. 从图像中随机取两个边缘点,求直线通过方程 通过他们。
  3. 找到m,图像中距离为d像素的其他边缘点的数量 线。
  4. 如果m > n,请转到步骤5。

    否则 (m ≤ n),将 t 增加 1,如果 t < tm 转到步骤 2,并且 if t ≥ tm 退出程序。

  5. 画线并删除距离它的d像素距离内的边缘点 图片。然后,转到第 1 步

基本上,我只是想从图像中随机选择两个点,找到它们之间的距离,如果距离太小,我会检测它们之间的一条线。

如果提供一个小代码 sn-p 来帮助我入门,我将不胜感激。 这更像是 RANSAC 参数线检测。如果我完成了,我也会更新这篇文章。

/* Display Routine */

#include "define.h"

ByteImage bimg;                     //A copy of the image to be viewed
int width, height;                  //Window dimensions
GLfloat zoomx = 1.0, zoomy = 1.0;   //Pixel zoom
int win;                            //Window index

void resetViewer();

void reshape(int w, int h) {
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
if ((w!=width) || (h!=height)) {
    zoomx=(GLfloat)w/(GLfloat)bimg.nc;
    zoomy=(GLfloat)h/(GLfloat)bimg.nr;
    glPixelZoom(zoomx,zoomy);
}
width=w; height=h;

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void mouse(int button, int state, int x, int y) {
glutPostRedisplay();
if((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN) &&
    (zoomx==1.0) && (zoomy==1.0)){
printf(" row=%d, col=%d, int=%d.\n", y,x, (int)bimg.image[(bimg.nr-1-y)*bimg.nc+x]);
        glutPostRedisplay();
}
}

void display() {
glClear(GL_COLOR_BUFFER_BIT);
glRasterPos2i(0, 0);         
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glDrawPixels((GLsizei)bimg.nc,(GLsizei)bimg.nr,   GL_LUMINANCE,GL_UNSIGNED_BYTE, bimg.image);
glutSwapBuffers();
}

【问题讨论】:

  • 检查 OpenCV 示例和函数。 HoughLines function 可能是您可以使用的东西。 OpenCV 还提供了检测边缘、features 和其他东西的功能。
  • 我知道 houghlines,并且 houghlinesP 检测线,但我想尝试实现上述算法。

标签: c++ algorithm line implementation ransac


【解决方案1】:

假设您有一个int[XDIMENSION][YDIMENSION]

令 t=0。

int t = 0; // ;-)

从图像中随机取两个边缘点,求出穿过它们的线的方程。

蛮力:你可以随机搜索图像中的点,当它们不是边缘点时重新搜索

struct Point {
  int x;
  int y;
};

bool is_edge(Point a) {
  return image[a.x][a.y] == 255;
}

int randomUpto(int upto) {
  int r = rand() % upto;
  return r;
}

,需要通过

初始化伪随机数生成器
srand(time(NULL));

寻找边缘点

  Point a;
  do {
    a.x = randomUpto(XDIMENSION);
    a.y = randomUpto(YDIMENSION);
  } while ( ! is_edge(a) );

查找m,图像中距离线d 像素内的其他边缘点的数量。

您需要点之间的线。一些搜索产生this fine answer,这导致

std::vector<Point> getLineBetween(Point a, Point b) {
  double dx = b.x - a.x;
  double dy = b.y - a.y;
  double dist = sqrt(dx * dx + dy * dy);
  dx /= dist;
  dy /= dist;
  std::vector<Point> points;
  points.push_back(a);
  for ( int i = 0 ; i < 2*dist; i++ ) {
    Point tmp;
    tmp.x = a.x + (int)(i * dx /2.0);
    tmp.y = a.y + (int)(i * dy /2.0);
    if ( tmp.x != points.back().x
     || tmp.y != points.back().y ) {
      points.push_back(tmp);
    }
  }
  return points;
}

你在这里看到一个模式吗?将步骤分成子步骤,询问谷歌,查看the documentation,尝试一些东西直到它有效。

你的下一步可能是

  • 创建一个distance function,欧几里得就足够了
  • 根据距离函数查找线旁(或点旁,更简单)的所有点

尝试一些,如果您仍然需要帮助,请回来。

【讨论】:

  • 我需要在加载图像文件后这样做吗?
  • 现在我可以加载和显示图像,但是如何检测该图像中的线条?,下面是代码,我只需要知道在“案例3:”中应该做什么
猜你喜欢
  • 2021-05-08
  • 1970-01-01
  • 2017-07-25
  • 1970-01-01
  • 2013-07-02
  • 2018-06-10
  • 2013-11-01
  • 2014-07-05
  • 1970-01-01
相关资源
最近更新 更多