Перейти к содержимому
Compvision.ru

kazanOpenCV

Пользователи
  • Количество публикаций

    27
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные пользователем kazanOpenCV


  1. если findContours с CV_CHAIN_APPROX_NONE выдаст нормальные точки в углах, то потом можно самому точки преобразовать с 4-х связностью в отрезки.

    mrgloom, так я и использовал CV_CHAIN_APPROX_SIMPLE, чтобы исключить ручную обработку точек контура на предмет исключения прямых отрезков.


  2. Доброго времени суток,

    возникла проблема с findContours. Вопрос в следующем:

    есть квадрат: contours[1]([4]({x=10 y=10 },{x=110 y=10 },{x=110 y=110 },{x=10 y=110 })).

    Рисуем его на белом фоне черным цветом с черной заливкой. Убираем грани, т.е. уменьшаем каждую сторону квадрата на толщину 1 пиксел.

    С помощью cv::findContours( empty_image, contours_optimized,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE); находим все контура на картинке, получаем:

    [0] [8]({x=10 y=11 },{x=11 y=10 },{x=109 y=10 },{x=110 y=11 },{x=110 y=109 },{x=109 y=110 },{x=11 y=110 },{x=10 y=109 }) - искомый контур.

    [1] [4]({x=1 y=1 },{x=1 y=1078 },{x=1918 y=1078 },{x=1918 y=1 }) - контур по периметру картинки

    Вопрос, почему найденный контур [8]({x=10 y=11 },{x=11 y=10 },{x=109 y=10 },{x=110 y=11 },{x=110 y=109 },{x=109 y=110 },{x=11 y=110 },{x=10 y=109 }) отличается от [4]({x=10 y=10 },{x=110 y=10 },{x=110 y=110 },{x=10 y=110 })??

    Т.е почему он находит контур как на рис.1, а не как на рис.2 строгий квадрат?

    post-5772-0-24046900-1365015665_thumb.pn


  3. Smorodov, спасибо за очередную порцию полезных идей.

    По п.0) если умножить все значения, например на 10, то разве "прыжков" станет меньше? Или же усиливать только "окрестности" значений, соответствующих началу и концу отрезка.

    По поводу п.1) можно поподробнее? не совсем понял.


  4. Всем доброго времени суток,

    на картинке слева результат работы Gimp'а, справа моего алгоритма.

    Пока еще дорабатываю, остаются вопросы по скорости и по детализации мелких деталей. Вообщем есть большое поле для оптимизации.

    Smorodov, mrgloom большое вам спасибо за ощутимую помощь, думаю еще возникнут вопросы и не раз)

    post-5772-0-41065200-1361514583_thumb.jp


  5. Пришла в голову идея определять вес ребра, соединяющего 2 пикселя, как Weight ((i,j); (i1,j1))=(Max - 1/2*(img(i,j)+img(i1,j1)))*koef;

    koef=sqrt(2) для диагональных ребер, =1 для верикальных и горизонтальных ребер. Max-для grayscale =255, для чернобелого изображения =1.

    Возможно в этом случае кратчайший путь будет идти по границе, а не скакать по диагоналям как на рисунке 1 в посте №32.


  6. так зачем до всех остальных то искать? надо же всего между двумя точками найти.

    mrgloom, так Dijkstra, насколько, я понял работает именно перебором всех узлов графа.

    Если координаты концов отрезка (x1,y1)-(x2,y2), то получается прямоугольный граф с количеством узлов N=(x2-x1+1)*(y2-y1+1)

    и количеством ребер L=(x2-x1-1)*(y2-y1-1)*8+ //серединные пиксели - у них по 8 связей со всеми остальными

    +(width-2)*2*5+(height-2)*2*5+ //краевые пиксели без угловых - у них по 5 связей со всеми остальными

    +4*3; //угловые пиксели - у них по 3 связи со всеми остальными

    Upd. Единственное, можно остановиться когда дойдем до узла, соответствующего концу отрезка, но как много узлов будет уже посещено до этого зависит

    от характера картинки. Но в среднем, конечно это ускорит выполнение алгоритма.


  7. Smorodov, да, я использую кусок исходного изображения соответствующий отрезку.

    Исходник на CUDA смотрел, но там нужно подключать Boost Graph Library, не хотелось бы.

    Пока реализовал сам на основе кода с priority_queue, выкладываю программу, если будет время посмотрите, пожалуйста.

    Там небольшая проблемка (см. приложенный рисунок). На рисунке тестовое изображение 10x10 пикселов. Черная горизонтальная полоса на уровне второго пиксела сверху на белом фоне.

    Граф состоит из 100 вершин. Веса для соединяющих ребер нахожу как в http://www.cs.washington.edu/education/courses/cse455/02wi/projects/project1/project1.htm (см. рис.2).

    В итоге кратчайший путь из 10 вершины в 9 определяется как показано красной линией (т.е. путь из номеров пикселов 10-1-12-3-14-5-16-7-18).

    Вероятно я что то делаю не так.

    post-5772-0-31605300-1361337271_thumb.jp

    Dijkstra.rar

    post-5772-0-74364800-1361338006_thumb.jp


  8. Для куска изображения размером 200x200 пикселов (количество вершин графа 40 000),

    время выполнения алгоритма поиска кратчайшего пути от заданной точки до всех остальных ~25 секунд.

    Что-то многовато. Если 1920x1080 то совсем долго будет.

    Как же, интересно, реализуют подобные алгоритмы в gimp или photoshope.

    Smorodov, mrgloom, может быть есть соображения по оптимизации?


  9. Smorodov, спасибо за ссылку.

    Нашел вот такой алгоритм Дейкстры.

    он ищет минимальную "стоимость пути" от исходного узла до всех узлов.

    Чтобы сформировать цепочку из узлов я добавил код с комментарием //kazanOpenCV 18.02.2013.

    Еще не проверял, вечером попробую скомпилировать.

    #include <cstdio>
    
    #include <queue>
    
    #include <vector>
    
    using namespace std;
    
    
    #define MAX 100001
    
    #define INF (1<<20)
    
    #define DEBUG if(0)
    
    #define pii pair< int, int >
    
    #define pb(x) push_back(x)
    
    
    struct comp {
    
        bool operator() (const pii &a, const pii &B )/>/>/>/> {
    
            return a.second > b.second;
    
        }
    
    };
    
    
    priority_queue< pii, vector< pii >, comp > Q;
    
    vector< pii > G[MAX];
    
    int D[MAX];
    
    bool F[MAX];
    
    
    int main() {
    
        int i, u, v, w, sz, nodes, edges, starting;
    
    
    //kazanOpenCV 18.02.2013 
    
      vector<vector<int> > e;
    
    
    
        DEBUG freopen("in.txt","r", stdin);
    
    
        // create graph
    
        scanf("%d %d", &nodes, &edges);
    
        for(i=0; i<edges; i++) {
    
            scanf("%d %d %d", &u, &v, &w);
    
            G[u].pb(pii(v, w));
    
            G[v].pb(pii(u, w)); // for undirected
    
        }
    
        scanf("%d", &starting);
    
    
        // initialize graph
    
        for(i=1; i<=nodes; i++) D[i] = INF;
    
    
    
    
    //kazanOpenCV 18.02.2013 
    
    
     for(i=1; i<=nodes; i++) e.push_back(vector<int>()); - начальное заполнение массива векторов пустыми векторами
    
    
    
        D[starting] = 0;
    
        Q.push(pii(starting, 0));
    
    
        // dijkstra
    
        while(!Q.empty()) {
    
            u = Q.top().first;
    
            Q.pop();
    
            if(F[u]) continue;
    
            sz = G[u].size();
    
            DEBUG printf("visiting from %d:", u);
    
            for(i=0; i<sz; i++) {
    
                v = G[u][i].first;
    
                w = G[u][i].second;
    
                if(!F[v] && D[u]+w < D[v]) {
    
                    DEBUG printf(" %d,", v);
    
                    D[v] = D[u] + w;
    
    
    
    
    //kazanOpenCV 18.02.2013 
    
    
    //std::vector<int> newvector(oldvector); -копирование одного вектора в другой
    
    
    
    std::vector<int> e[v](e[u]);//-копирование одного вектора в другой
    
    
    // vector<vector<int> > e;
    
    // e.push_back(vector<int>());
    
    
    e[v].push_back(u);//вставка элемента u в конец цепочки узлов в пути
    
    
    
                    Q.push(pii(v, D[v]));
    
                }
    
            }
    
            DEBUG printf("\n");
    
            F[u] = 1; // done with u
    
        }
    
    
        // result
    
        for(i=1; i<=nodes; i++) printf("Node %d, min weight = %d\n", i, D[i]);
    
        return 0;
    
    }


  10. Добрый день, на скриншоте результат - третье маленькое окно сверху с белым контуром.

    Белый контур - это попиксельно найденный c помощью Sobel.

    Есть проблема когда в фрагменте несколько ощутимызх перепадов яркости, как быть в этом случае?

    Нужно искать максимум по каким-то критериям.

    Вообщем застопорился.

    post-5772-0-18907800-1361019686_thumb.jp


  11. "Спустился" до уровня отдельных пикселов.

    Как задать некую аггрегатную характеристику (учитывающую в общем случае яркость, цветность и т.п.) отдельного пикселя, чтобы сравнивать между их собой, проходя вдоль линии?

    Соответственно, найдя глобальный максимум на линии, можно предположить, что именно там и есть граница.


  12. Всем доброго времени суток!

    Спасибо Smorodov и mrgloom за идеи.

    Smorodov, змеи предполагают замкнутый начальный контур? Если так то не совсем подходит.

    Продолжаю "копать" в этом направлении.

    Набросал алгоритм, прошу высказать идеи и замечания.

    Итак, есть исходная картинка (рис.1)

    Далее вручную (мышью) задается грубый ломаный контур (в общем случае незамкнутый) для определенного объекта на картинке (например, в нашем случае - часть верхнего контура антилопы).Рис.2.

    Задается максимальная удаленность (d1) от отрезка исходного грубого контура и точность (d2) - частота точек на уточненном контуре.

    Затем необходимо найти уточненный контур исходя из заданного грубого контура и критериев d1 и d2.

    Предполагается следующий алгоритм:

    1) Ограничиваю область поиска прямоугольной областью, описывающую исходный грубый ломаный контур - minAreaRect.

    2) перевод в градации серого

    3) размытие (?)

    4) adaptiveThreshold

    5) FindContours

    6) строим перпендикулярные прямые (в обе стороны на длину d1) на каждом отрезке исходного грубого контура (через расстояние d2) и ищем пересечение с найденными в п.5. контурами (?) - рис.3 Далее также по каждому отрезку.

    7) Объединяем найденные точки в единый уточненный контур.

    В чем могут быть подводные камни и как лучше реализовать алгоритм?

    post-5772-0-81515300-1360739531_thumb.jp

    post-5772-0-00115200-1360739654_thumb.jp

    post-5772-0-95696200-1360740503_thumb.jp


  13. mrgloom, есть исходный кадр (например, как в первом посте, в котором есть какие-то объекты), задается грубый контур в виде набора точек (передается извне),

    также задается расстояние между точками уточненного контура, а также максимальное удаление точки уточненного контура от исходного грубого.

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

×