Форум программистов, компьютерный форум CyberForum.ru

Opencv cvFindContours - нахождение контуров и сортировка по горизонтали - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.71
gore-lykovoe
 Аватар для gore-lykovoe
31 / 31 / 1
Регистрация: 04.04.2010
Сообщений: 414
15.05.2014, 01:10     Opencv cvFindContours - нахождение контуров и сортировка по горизонтали #1
Он находит контуры и сортирует их по вертикали по-умолчанию. Как сделать, чтобы сортировал по горизонтали. Писал костыль, используя переменную "x" в контуре, но он неправильно отрабатывает иногда почему-то. Вот думаю может средствами opencv можно сделать.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.05.2014, 01:10     Opencv cvFindContours - нахождение контуров и сортировка по горизонтали
Посмотрите здесь:

C++ найти количество всех путей и контуров графа длиной S
Поиск всех контуров в ориентированном графе C++
OpenCV C++
OpenCV C++
C++ Заполнение квадратной матрицы змейкой по горизонтали
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
iRomul
 Аватар для iRomul
158 / 99 / 11
Регистрация: 17.10.2012
Сообщений: 474
Завершенные тесты: 1
15.05.2014, 04:33     Opencv cvFindContours - нахождение контуров и сортировка по горизонтали #2
Сообщение было отмечено автором темы, экспертом или модератором как ответ
gore-lykovoe, а если попробовать перевернуть изображение? Так, что бы горизонталь стала вертикалью
gore-lykovoe
 Аватар для gore-lykovoe
31 / 31 / 1
Регистрация: 04.04.2010
Сообщений: 414
15.05.2014, 10:31  [ТС]     Opencv cvFindContours - нахождение контуров и сортировка по горизонтали #3
Цитата Сообщение от iRomul Посмотреть сообщение
а если попробовать перевернуть изображение? Так, что бы горизонталь стала вертикалью
Хорошая идея. Спасибо, попробую.

Добавлено через 1 час 10 минут
Блин, так тоже иногда криво сортирует. Значит изначально он сортирует не по вертикали, а как-то особоенно. Подскажите пожалуйста.

Добавлено через 2 минуты
Для прохода по контурам я использую contours->h_next

Добавлено через 9 минут
Я вот так выделяю http://blog.damiles.com/2010/12/segm...lob-detection/
iRomul
 Аватар для iRomul
158 / 99 / 11
Регистрация: 17.10.2012
Сообщений: 474
Завершенные тесты: 1
15.05.2014, 20:14     Opencv cvFindContours - нахождение контуров и сортировка по горизонтали #4
gore-lykovoe, скиньте код
gore-lykovoe
 Аватар для gore-lykovoe
31 / 31 / 1
Регистрация: 04.04.2010
Сообщений: 414
16.05.2014, 17:20  [ТС]     Opencv cvFindContours - нахождение контуров и сортировка по горизонтали #5
Цитата Сообщение от iRomul Посмотреть сообщение
gore-lykovoe, скиньте код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//-------------------------------------------------------------------------------------
// помогает упорядочивать контуры горизонтально
struct ProcessingImage::Hor {
    int x;
    int i;
    friend bool operator < (Hor const &a, Hor const &b) {
        return a.x < b.x;
    }
};
//-------------------------------------------------------------------------------------
void ProcessingImage::SortHor(Hor *a, int n) {
    int j = 0;
    for (int i = 1; i < n; ++i) {
        Hor temp = a[i];
        for (j = i; j > 0 && temp < a[j - 1]; --j) {
            a[j] = a[j-1];
        }
        a[j] = temp;
    }
}
//-------------------------------------------------------------------------------------
// получение матриц контуров (символов)
QVector<Matrix> ProcessingImage::get_contours_pixels() {
    if (!approx_contours) {
        throw UninitializedData("Uninitialized approx_contours "
                                "ProcessingImage::get_contours_pixels()");
    }
    CvSeq* copy_approx_contours = approx_contours;
    int k = 0; // количество контуров
    // находим количестве контуров
    for(; copy_approx_contours != 0; copy_approx_contours = copy_approx_contours->h_next, ++k );
    Hor hor[k];
    CvMat data;
    CvSeq* approx_contours2 = approx_contours;
    for(int z = 0; approx_contours2 != 0; approx_contours2 = approx_contours2->h_next, ++z ) {
            CvPoint* p = (CvPoint*)cvGetSeqElem(approx_contours2, z);
            if (!p) {
                throw UninitializedData("Uninitialized p "
                                        "ProcessingImage::get_contours_pixels()");
            }
            hor[z].i = z;
            hor[z].x = p->x;
    }
 
    // упорядочиваем контуры горизонтально
   SortHor(hor, k);
   QVector<Matrix> input_list;
   Matrix input[k];
 
    for(int t = 0; approx_contours != 0; approx_contours = approx_contours->h_next, ++t)
    {
        // получаем прямоугольный контур
        CvRect rect=cvBoundingRect(approx_contours, NULL);
        cvGetSubRect(threshold_smooth_gray_image, &data, rect);
        cv::Mat convData = cv::Mat(&data);
        cv::Mat scaledConvData;
        // изменяем размер
        cv::resize(convData, scaledConvData, cv::Size(col, row), 0, 0, CV_INTER_NN);
        data = scaledConvData;
 
        Matrix countour_pixels;
        // получаем писксели контура
        for (int i = 0; i < data.rows; ++i) {
            uchar* ptr = (uchar*) (data.data.ptr + i * data.step);
            if (!ptr) {
                throw UninitializedData("Uninitialized ptr"
                                        "ProcessingImage::get_contours_pixels()");
            }
            for (int j = 0; j < data.cols; ++j) {
                if (ptr[j] == 255)
                    countour_pixels[i][j] = 1;
                else
                    countour_pixels[i][j] = 0;
            }
        }
        input[hor[t].i] = countour_pixels;
 
    }
 
    for (int i = 0; i < k; ++i) {
        input_list.push_back(input[i]);
    }
 
    return input_list;
}
Гавнокод, но это временно. Первый раз пробегаюсь по контурам чтобы получить их число в "k". Потом пробегаюсь еще раз по ним чтобы загнать в структуру Hor координату и порядковый номер. Потом уже кладу в контейнер данные. На выходе иногда данные перемешанные случайным образом.

Добавлено через 6 минут
На 2 контурах он сортирует всегда правильно. Если 3 контура то иногда неправильно. Если 5 и больше, то всегда неправильно практически.
С перевернутым изображением код был такой же, только убрал сортировку, структуру и два ненужных прогона.
iRomul
 Аватар для iRomul
158 / 99 / 11
Регистрация: 17.10.2012
Сообщений: 474
Завершенные тесты: 1
16.05.2014, 20:13     Opencv cvFindContours - нахождение контуров и сортировка по горизонтали #6
gore-lykovoe, вы можете показать какой-нибудь пример? Что бы было визуально ясно, что выдаёт программа и что нужно получить. Я у себя попробую.
gore-lykovoe
 Аватар для gore-lykovoe
31 / 31 / 1
Регистрация: 04.04.2010
Сообщений: 414
16.05.2014, 21:36  [ТС]     Opencv cvFindContours - нахождение контуров и сортировка по горизонтали #7
iRomul,
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
00001111100000000000
00111111111000000000
01111111111100000000
11100000001110000000
01000000000110000000
00000000000110000000
00000000000111000000
00000000000011000000
00000000000011000000
00000000000011000000
00000000000011000000
00000000000011000000
00000000000011000000
00000000000111000000
00000000000110000000
00000000001111000000
00000000001111110000
00000000000101111000
00000000000000111100
00000000000000001110
00000000000000001110
00000000000000000111
00000000000000000011
00000000000000000011
00000000000000000011
00000000000000000011
00000000000000000011
00000000000000000111
00000000000000001110
00000000000000011100
00000000000000111100
00000000111111111000
00000000111111100000
 
00000001100000000000
00000011111000000000
00000011111111000000
00000011011111111100
00000011000011111111
00000011000000001111
00000011000000000011
00000011000000000000
00000011000000000000
00000011000000000000
00000011000000000000
00000011000000000000
00000011000000000000
00000011000000000000
00000011000000000000
00000011000000000000
00000011001110000000
00000011111111000000
00000011111111110000
00000001100001110000
00000000000000111000
00000000000000011100
00000000000000001100
00000000000000001100
00000000000000001100
00000000000000001100
00000000000000001100
01100000000000011100
11100000000000111000
01110000001111111000
00111000111111110000
00011111111110000000
00011111110000000000
 
00001100000000000000
00011100000000000000
00111110000000000000
00111111000000000000
01110111000000000000
01100001100000000000
11100001100000000000
11000001100000000000
11000000110000000000
00000000110000000000
00000000110000000000
00000000110000000000
00000000011000000000
00000000011000000000
00000000011000000000
00000000011000000000
00000000011000000000
00000000011000000000
00000000011000000000
00000000011000000000
00000000011000000000
00000000110000000000
00000000110000000000
00000000110000000000
00000001110000000000
00000001100000000000
00000011100000000000
00000011000000000000
00001111000000000000
00011111111000000000
00011111111111000000
00011111111111111111
00000000001111111111
 
00000000000000000111
00000000000000001111
00000000000000001111
00000000000000011111
00000000000000111111
00000000000001111110
00000000000111111110
00000000001111111100
00000000011111111100
00000001111111111000
00000111111101111000
00011111110001111000
01111111000011110000
11111000000011110000
11110000000111110000
00000000000111100000
00000000001111000000
00000000001111000000
00000000001111000000
00000000001110000000
00000000011110000000
00000000111110000000
00000000111110000000
00000000111100000000
00000001111000000000
00000001111000000000
00000001111000000000
00000011110000000000
00001111110000000000
00001111110000000000
00001111100000000000
00001111100000000000
00001111100000000000
 
11110000000000000000
11110000000000000000
11110000000000000000
11110000000000000000
11110000000000000000
11110000000000000000
11110000000000000000
11110000000000000000
11111000000000000000
11111000000000001110
01111000000000011111
01111000000000111111
01111000000001111111
00111000000011111111
00111110000111110111
00111111001111100111
00001111111111000111
00001111111110000111
00000111111000000111
00000000000000000111
00000000000000000111
00000000000000000111
00000000000000000111
00000000000000000111
00000000000000000111
00000000000000000111
00000000000000000111
00000000000000001111
00000000000000001111
00000000000000001111
00000000000000001111
00000000000000001110
00000000000000001110
 
00000000001111100000
00000000011111110000
00000000111111111000
00000001111100111100
00000001111000011100
00000011110000001000
00000111000000000000
00001111000000000000
00001110000000000000
00011110000000000000
00011110000000000000
00011100000000000000
00111100000000000000
00111000000000000000
00111000011110000000
01111000111111100000
01110001111111110000
01110011110011111100
11110111100000111110
11111111000000011111
11111110000000001111
11111110000000000111
11111110000000000011
11111100000000000011
01111000000000000011
01111000000000000111
01111000000000001111
00111100000000011111
00011110000001111100
00001110000011111000
00001111101111100000
00000111111111000000
00000011111110000000
т.е. не в том порядке цифры
Миниатюры
Opencv cvFindContours - нахождение контуров и сортировка по горизонтали  
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.05.2014, 22:09     Opencv cvFindContours - нахождение контуров и сортировка по горизонтали
Еще ссылки по теме:

C++ Ранжирование вершин на ориентированном графе без контуров по отношению к вершине
C++ Клеим csv по горизонтали
C++ Заливка контуров в текстовом файле

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
iRomul
 Аватар для iRomul
158 / 99 / 11
Регистрация: 17.10.2012
Сообщений: 474
Завершенные тесты: 1
16.05.2014, 22:09     Opencv cvFindContours - нахождение контуров и сортировка по горизонтали #8
Сообщение было отмечено автором темы, экспертом или модератором как ответ
gore-lykovoe, ну у меня программа была другая, с сайта OCV взял, но результат примерно аналогичный для этой картинки. Я не сильно знаком со спецификой работы OCV и сейчас разбираюсь в другой области, но что могу посоветовать:
1) Обратиться на stackoverflow. Это крупнейшее Q&A сообщество, и там обитает гораздо больше специалистов по OpenCV. Боюсь, что на этом форуме немногие смогут вам помочь с этой библиотекой.
2) Попробовать вручную разделить изображения на области (для тривиальных случаев вроде этого) и в каждой области уже искать контур. Получится, что контур будет единственным в области и составить их последовательность уже не составит труда. Для облегчения задачи может помочь бинаризация.
Yandex
Объявления
16.05.2014, 22:09     Opencv cvFindContours - нахождение контуров и сортировка по горизонтали
Ответ Создать тему
Опции темы

Текущее время: 08:46. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru