Реализация алгоритма обнаружения признаков

Я новичок в программировании и хотел бы знать, как начать реализацию следующего алгоритма на C++,

Для бинарного изображения, в котором пиксели с интенсивностью 255 показывают края, а пиксели с интенсивностью 0 показывают фон, найдите в изображении сегменты линий длиннее n пикселя. t — это счетчик, показывающий количество итераций без нахождения строки, а tm — максимально допустимое количество итераций до выхода из программы.

  1. Пусть t=0.
  2. Возьмите случайным образом две крайние точки изображения и найдите уравнение прямой, проходящей через них.
  3. Найдите m, количество других краевых точек изображения, находящихся на расстоянии d пикселей от линии.
  4. Если m > n, перейдите к шагу 5.

    В противном случае (m ≤ n) увеличить t на 1 и, если t < tm, перейти к шагу 2, а если t ≥ tm, выйти из программы.

  5. Нарисуйте линию и удалите краевые точки, находящиеся на расстоянии d пикселей от нее, от изображения. Затем перейдите к шагу 1

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

Я был бы признателен, если бы для начала был предоставлен небольшой фрагмент кода. это больше похоже на параметрическое обнаружение линии 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();
}

person TheAmateur    schedule 13.10.2015    source источник
comment
Проверьте примеры и функции OpenCV. Вы можете использовать функцию HoughLines. OpenCV также предоставляет функции для обнаружения границ, функции и другие вещи. .   -  person wendelbsilva    schedule 13.10.2015
comment
Я знаю, что houghlines и houghlinesP обнаруживают линии, но я хочу попытаться реализовать описанный выше алгоритм.   -  person TheAmateur    schedule 13.10.2015


Ответы (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 пикселей от линии.

Вам нужна линия между точками. Некоторый поиск дает этот прекрасный ответ, что приводит к

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;
}

Вы видите здесь закономерность? Разделите шаги на подшаги, спросите Google, посмотрите документацию, попробуйте из вещей, пока это не работает.

Ваши следующие шаги могут заключаться в

  • создайте функцию расстояния, евклидова должно хватить
  • найти все точки рядом с линией (или рядом с точкой, что проще) на основе функции расстояния

Попробуйте некоторые из них и вернитесь, если вам все еще нужна помощь.

person serv-inc    schedule 13.10.2015
comment
мне нужно сделать это после загрузки файла изображения, верно? - person TheAmateur; 14.10.2015
comment
прямо сейчас я могу загрузить и отобразить изображение, но как мне обнаружить линии на этом изображении? Ниже приведен код, мне просто нужно знать, что делать в случае 3: - person TheAmateur; 14.10.2015