Алгоритм утоньшения изображения
От: xmlx  
Дата: 11.08.08 13:56
Оценка: :)
Есть изображение буквы L
000000000
001000000
001100000
001100000
001000000
001001100
001111100
000000000


Как сделать алгоритм, который приведёт к утоньшения этой буквы L, к
такому виду, что у любой "1" было только две или только одна соседняя "1"
000000000
001000000
001000000
001000000
001000000
001000000
001111100
000000000

Понимаю, что задача имеет множество решений. нужно найти оптимальное.
Re: Алгоритм утоньшения изображения
От: Were  
Дата: 11.08.08 14:59
Оценка:
Здравствуйте, xmlx, Вы писали:

X>Как сделать алгоритм, который приведёт к утоньшения этой буквы L, к

X>такому виду, что у любой "1" было только две или только одна соседняя "1"

Topological skeleton
Внизу есть ссылки на алгоритмы.
Re[2]: Алгоритм утоньшения изображения
От: xmlx  
Дата: 11.08.08 18:15
Оценка:
Здравствуйте, Were, Вы писали:

W>Здравствуйте, xmlx, Вы писали:


X>>Как сделать алгоритм, который приведёт к утоньшения этой буквы L, к

X>>такому виду, что у любой "1" было только две или только одна соседняя "1"

W>Topological skeleton

W>Внизу есть ссылки на алгоритмы.

я всё это прочитал. к сожалению, это не то что нужно.
у меня скелетонизация выполняется в два этапа. на первом — distance transform, вот после первого этапа получается изображение с "переменной толшиной" от 1 до 2 пикселей и нужно сделать заключительное утоньшение, оставив связное изображение толщиной точно в 1 пиксел. Я уже сделал такой алгоритм и он прекрасно работает, но мне он не совсем нравится, он не оптимальный. Может есть какие-то более "умные варианты"?
Re[3]: Алгоритм утоньшения изображения
От: Were  
Дата: 11.08.08 22:53
Оценка:
Здравствуйте, xmlx, Вы писали:

X>Здравствуйте, Were, Вы писали:


W>>Здравствуйте, xmlx, Вы писали:


X>>>Как сделать алгоритм, который приведёт к утоньшения этой буквы L, к

X>>>такому виду, что у любой "1" было только две или только одна соседняя "1"

W>>Topological skeleton

W>>Внизу есть ссылки на алгоритмы.

X>я всё это прочитал. к сожалению, это не то что нужно.

X>у меня скелетонизация выполняется в два этапа. на первом — distance transform, вот после первого этапа получается изображение с "переменной толшиной" от 1 до 2 пикселей и нужно сделать заключительное утоньшение, оставив связное изображение толщиной точно в 1 пиксел. Я уже сделал такой алгоритм и он прекрасно работает, но мне он не совсем нравится, он не оптимальный. Может есть какие-то более "умные варианты"?

Я как-то делал скелетонизацию, но посеял pdf с алгоритмом (может позже найду). Остался только код:

void Skeletize()
{
    int x, y,
        n[8], 
        A, B,
        subiter = 0;

    bool bFound, bFound1 = true, bFound2 = true;

    while( bFound1 || bFound2 )
    {
        for ( y = 0; y < m_Height; y++ )
        {
            for ( x = 0; x < m_Width; x++ )
            {   
                if ( !At( x, y ))
                    continue;

                n[0] = At( x, y - 1 );
                n[1] = At( x + 1, y - 1 );
                n[2] = At( x + 1, y);
                n[3] = At( x + 1, y + 1 );
                n[4] = At( x, y + 1 );
                n[5] = At( x - 1, y + 1 );
                n[6] = At( x - 1, y );
                n[7] = At( x - 1, y - 1 );

                B = 0 != n[0];
                B += 0 != n[1];
                B += 0 != n[2];
                B += 0 != n[3];
                B += 0 != n[4];
                B += 0 != n[5];
                B += 0 != n[6];
                B += 0 != n[7];
            
                if ( B < 2 || B > 6 )
                    continue;

                A = !n[0] && n[1];
                A += !n[1] && n[2];
                A += !n[2] && n[3];
                A += !n[3] && n[4];
                A += !n[4] && n[5];
                A += !n[5] && n[6];
                A += !n[6] && n[7];
                A += !n[7] && n[0];
            
                if ( A != 1 )
                    continue;

                if ( subiter == 0 &&
                    ( n[0] && n[2] && n[4] ||
                    n[2] && n[4] && n[6] ))
                    continue;

                if ( subiter == 1 &&
                    ( n[0] && n[2] && n[6] ||
                    n[0] && n[4] && n[6] ))
                    continue;

                At( x, y ) = 2;
            }
        }

        bFound = false;

        for ( y = 0; y < m_Height; y++ )
        {
            for ( x = 0; x < m_Width; x++ )
            {
                int &v = At( x, y );

                if ( v == 2 ) 
                {
                    bFound = true;
                    v = 0;
                }
            }
        }

        if ( subiter == 0 )
            bFound1 = bFound;
        else
            bFound2 = bFound;


        subiter = !subiter;
    }

}


Небольшой комментарий:
Skeletize() — метод класса бинарного поля.
m_Height, m_Width — ширина и длина поля.
At() — метод, возвращающий ссылку на элемент поля. Если координаты вне поля, то ссылку на временный элемент.
Re: Алгоритм утоньшения изображения
От: Аноним  
Дата: 15.08.08 11:34
Оценка:
Здравствуйте, xmlx, Вы писали:


X>
X>000000000
X>001000000
X>001000000
X>001000000
X>001000000
X>001000000
X>001111100
X>000000000
X>

X>Понимаю, что задача имеет множествоqwq решений. нужно найти оптимальное.

1.Просматриваешь изображение через окно 3x3
2.Если в центре окна 0 — нечего не делать
3.Если в центре окна 1, то
если граничные клетки содержат только одно связное множество единиц и кол-во единиц в нём >2, но меньше 8- записать в центральную клетку 0
4.Сдвинуть окно на шаг.

Примеры на картинках:

000 000 001 001 111 111
011 ->001 010 ->010 110->100 и т.д.
011 011 010 010 111 111

Граничных клеток — 8. Комбинация 0 и 1 в них образует число щт 0 до 255. Строим таблицу и указываем в ней те комбинации, при которых в центральную клетку будет записываться 0.

Это почти реализация одного из вариантов игры "Жизнь". Важно, что вышеописанные операции надо проводить последовательно!
Re[2]: Алгоритм утоньшения изображения
От: True2008  
Дата: 15.08.08 20:41
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, xmlx, Вы писали:



X>>
X>>000000000
X>>001000000
X>>001000000
X>>001000000
X>>001000000
X>>001000000
X>>001111100
X>>000000000
X>>

X>>Понимаю, что задача имеет множествоqwq решений. нужно найти оптимальное.

А>1.Просматриваешь изображение через окно 3x3

А>2.Если в центре окна 0 — нечего не делать
А>3.Если в центре окна 1, то
А> если граничные клетки содержат только одно связное множество единиц и кол-во единиц в нём >2, но меньше 8- записать в центральную клетку 0
А>4.Сдвинуть окно на шаг.

А>Примеры на картинках:


А>000 000 001 001 111 111

А>011 ->001 010 ->010 110->100 и т.д.
А>011 011 010 010 111 111

А>Граничных клеток — 8. Комбинация 0 и 1 в них образует число щт 0 до 255. Строим таблицу и указываем в ней те комбинации, при которых в центральную клетку будет записываться 0.


а можете привести здесь эту таблицу? заранее thanx.
Re[2]: Алгоритм утоньшения изображения
От: True2008  
Дата: 15.08.08 21:04
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, xmlx, Вы писали:



X>>
X>>000000000
X>>001000000
X>>001000000
X>>001000000
X>>001000000
X>>001000000
X>>001111100
X>>000000000
X>>

X>>Понимаю, что задача имеет множествоqwq решений. нужно найти оптимальное.

А>1.Просматриваешь изображение через окно 3x3

А>2.Если в центре окна 0 — нечего не делать
А>3.Если в центре окна 1, то
А> если граничные клетки содержат только одно связное множество единиц и кол-во единиц в нём >2, но меньше 8- записать в центральную клетку 0
А>4.Сдвинуть окно на шаг.

А>Примеры на картинках:


А>000 000 001 001 111 111

А>011 ->001 010 ->010 110->100 и т.д.
А>011 011 010 010 111 111

А>Граничных клеток — 8. Комбинация 0 и 1 в них образует число щт 0 до 255. Строим таблицу и указываем в ней те комбинации, при которых в центральную клетку будет записываться 0.


А>Это почти реализация одного из вариантов игры "Жизнь". Важно, что вышеописанные операции надо проводить последовательно!


если не трудно, напишите таблицу, вот с таким порядком нумерации
012
7x3
654

thanx. сорри за дубль... забыл написать порядок нумерации...
Re[3]: Алгоритм утоньшения изображения
От: Аноним  
Дата: 16.08.08 16:07
Оценка:
Здравствуйте, True2008, Вы писали:

T>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, xmlx, Вы писали:



X>>>
X>>>000000000
X>>>001000000
X>>>001000000
X>>>001000000
X>>>001000000
X>>>001000000
X>>>001111100
X>>>000000000
X>>>

X>>>Понимаю, что задача имеет множествоqwq решений. нужно найти оптимальное.

А>>1.Просматриваешь изображение через окно 3x3

А>>2.Если в центре окна 0 — нечего не делать
А>>3.Если в центре окна 1, то
А>> если граничные клетки содержат только одно связное множество единиц и кол-во единиц в нём >2, но меньше 8- записать в центральную клетку 0
А>>4.Сдвинуть окно на шаг.

А>>Примеры на картинках:


А>>000 000 001 001 111 111

А>>011 ->001 010 ->010 110->100 и т.д.
А>>011 011 010 010 111 111

А>>Граничных клеток — 8. Комбинация 0 и 1 в них образует число щт 0 до 255. Строим таблицу и указываем в ней те комбинации, при которых в центральную клетку будет записываться 0.


А>>Это почти реализация одного из вариантов игры "Жизнь". Важно, что вышеописанные операции надо проводить последовательно!


T>если не трудно, напишите таблицу, вот с таким порядком нумерации

T>
T>012
T>7x3
T>654
T>

T>thanx. сорри за дубль... забыл написать порядок нумерации...
Алгоритм формирования таблицы.
Замена единицы на ноль происходит в тех случаях, когда граница содержит от 3 до семи подряд идущих (смежных) единиц (старшая единица и младшая считаются смежными).
Т.е. для трёх единиц — это случаи: 00000111, 00001110, 00011100, 00111000, 01110000, 11100000, 11000001, 10000011 (3,7,14,...).
— взять тройку и сдвигать её циклически влево (разряд из переполнения записывать в младший бит). А можно и вправо(не пробовал . Аналогично для четырёх и более единиц.
Таким образом, если биты границы образуют число 3 (7, 14, 15...), то центральный бит скользящего окна надо заменить но 0.
Конечно, результат(скелет двухградационного изображения) зависит от пути обхода. Но если сканировать изображение просто построчно, то в большинстве случаев этот алгоритм работает удовлетворительно.
Ну а уж выписывать таблицу — просто лень.
Re: Алгоритм утоньшения изображения
От: 8bit  
Дата: 17.08.08 16:09
Оценка:
Здравствуйте, xmlx, Вы писали:

Вот в этом документе описан The thinning algorithm,
который они взяли видимо из книги Digital Image Processing (Rafael C. Gonzalez, Richard E. Woods)
http://www.vision.auc.dk/~tbm/Student_projects/02-automatic.pdf
4.4.2 End points, страница 62 документа.

Есть его реализация в коде (должно работать ), если надо.
Re[4]: Алгоритм утоньшения изображения
От: True2008  
Дата: 17.08.08 18:52
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Конечно, результат(скелет двухградационного изображения) зависит от пути обхода. Но если сканировать изображение просто построчно, то в большинстве случаев этот алгоритм работает удовлетворительно.

А>Ну а уж выписывать таблицу — просто лень.

012
7x3
654


0000000100000011
0000000000001011
0000000000000000
0000000010001011
0000000000000000
0000000000000000
0000000000000000
1000000010001011
0001000100000001
0000000000000001
0000000000000000
0000000000000001
0101000100000001
0000000000000001
1101000100000001
1101000111011111


эта таблица?
Re[5]: Алгоритм утоньшения изображения
От: V52  
Дата: 18.08.08 02:56
Оценка:
Здравствуйте, True2008, Вы писали:

T>Здравствуйте, Аноним, Вы писали:


А>>Конечно, результат(скелет двухградационного изображения) зависит от пути обхода. Но если сканировать изображение просто построчно, то в большинстве случаев этот алгоритм работает удовлетворительно.

А>>Ну а уж выписывать таблицу — просто лень.

T>
T>012
T>7x3
T>654
T>


T>
T>0000000100000011
T>0000000000001011
T>0000000000000000
T>0000000010001011
T>0000000000000000
T>0000000000000000
T>0000000000000000
T>1000000010001011
T>0001000100000001
T>0000000000000001
T>0000000000000000
T>0000000000000001
T>0101000100000001
T>0000000000000001
T>1101000100000001
T>1101000111011111
T>


T>эта таблица?


byte Table[256];

Граничные биты --> i --> Table[i]
-------------- — --------
00000000 0 0
00000001 1 0
00000010 2 0
00000011 3 0
00000100 4 0
00000101 5 0
00000110 6 0
00000111 7 1
00001000 8 0
00001001 9 0
00001010 10 0
00001011 10 0
00001100 12 0
00001101 13 0
00001110 14 1
00001111 15 1
00010000 16 0
00010001 17 0
00010010 18 0
00010011 19 0
00010100 20 0
00010101 21 0
00010110 22 0
00010111 23 0
00011000 24 0
00011001 25 0
00011010 26 0
00011011 27 0
00011100 28 1
00011101 29 0
00011110 30 1
00011111 31 1
...
11111010 250 0
11111011 251 1
11111100 252 1
11111101 253 1
11111110 254 1
11111111 255 0
Такая должна получиться таблица.
Далее.
1. Из граничных битов окна формируем номер элемента таблицы.
2. Если элемент таблицы с этим номером равен 1, то центральный элемент окна заменяем на 0. (Т.е. центральный элемент окна является граничным и, в то же время, его удаление не приводит к разрывам и к появлению новых дырок.)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.