Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.07.2015, 16:37   #1
DarkHacker
Форумчанин
 
Аватар для DarkHacker
 
Регистрация: 12.04.2008
Сообщений: 105
По умолчанию Выделить контур на ч\б изображении

Здравствуйте. Есть изображение черно-белое (бинаризированное) необходимо начиная с заданного пикселя построить контур неразрывного объекта.
Было бы хорошо еще иметь возможность "вырезать" обьект и поставить и соседний TImage.

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

Есть ли готовые решения?

Спасибо.
DarkHacker вне форума Ответить с цитированием
Старый 06.07.2015, 17:08   #2
Luuzuk
Форумчанин
 
Аватар для Luuzuk
 
Регистрация: 18.01.2012
Сообщений: 975
По умолчанию

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

Готовые решения если и есть, то все равно подлежат допиливанию. Иногда быстрее немного поднапрячься и самому сделать
Благодарить в репутацию. Проклинать — туда же
Luuzuk вне форума Ответить с цитированием
Старый 06.07.2015, 17:46   #3
DarkHacker
Форумчанин
 
Аватар для DarkHacker
 
Регистрация: 12.04.2008
Сообщений: 105
По умолчанию

Цитата:
Сообщение от Luuzuk Посмотреть сообщение
А попробуйте метод обхода контура ("жука"), он достаточно прост, чтобы его можно было реализовать самостоятельно. ссылка на описание

Готовые решения если и есть, то все равно подлежат допиливанию. Иногда быстрее немного поднапрячься и самому сделать
Не совсем понимаю принцип работы, неужели "жук" при обходе поведет себ иначе чем в прикрепленном файле? Когда он достигнет точки отмеченной красной линией он будет всегда двигаться "прямо" или как реализовать "поворот туловища жука". Господи, я наверное несу бред)
Изображения
Тип файла: jpg Без имени.jpg (15.1 Кб, 118 просмотров)
DarkHacker вне форума Ответить с цитированием
Старый 06.07.2015, 18:34   #4
Luuzuk
Форумчанин
 
Аватар для Luuzuk
 
Регистрация: 18.01.2012
Сообщений: 975
По умолчанию

Не, жук по прямой двигаться не может принципиально
Если жук находится на белой клетке, то следующий шаг он сделает на клетку справа от себя. Если на черной - то на клетку слева от себя. Только не путайте право и лево "на картинке" с право и лево "жука". Если, например, жук последний шаг сделал по направлению к нижней границе картинки, то поворот "налево" будет означать шаг в сторону правой границы картинки. На вложенном рисунке пояснения.

Каждый шаг жука можно представить себе как прибавление или вычитание к/из одной из его координат (х и y) единицы

Т.е. "жук смотрит вправо, жук идет направо" описывается как "жук.Y = жук.Y-1;" (если за начало координат принять левый нижний угол рисунка). Следующий его ход "жук смотрит вниз, жук идет налево" будет выглядеть как "жук.X = жук.X+1;". Самое "сложное" здесь - это хранить направление последнего шага жука, чтобы понять какую координату и как менять при следующем шаге
Изображения
Тип файла: png Безымянный.png (21.8 Кб, 128 просмотров)
Благодарить в репутацию. Проклинать — туда же
Luuzuk вне форума Ответить с цитированием
Старый 07.07.2015, 22:48   #5
DarkHacker
Форумчанин
 
Аватар для DarkHacker
 
Регистрация: 12.04.2008
Сообщений: 105
По умолчанию

Нашел исходник на С , переписал, не работает. Сам сделать не могу(

Код:
function AlgorithmBeatle(FromImage,ToImage:TBitmap):byte;
var
    X,Y, cX, cY, b :integer;
    Line,ToLine:PByteArray;
    Direct_type:array [1..4] of string;
    Direct:byte;
    //'North'
begin

Direct_type[1]:='North';
Direct_type[2]:='East';
Direct_type[3]:='South';
Direct_type[4]:='West';

direct:=1;

    for Y:=0 to FromImage.Height do
    begin
      Line := FromImage.ScanLine[Y];
        for X:=0 to FromImage.Width do
        begin
            B := Line[X];
            if (B<255) then  break;
        end;
        // Если встречен объект, отличающийся от цвета фона (255 - белый)
        // прервать поиск
        if (X <> FromImage.Width) then  break;

    // Если не нашли ни одного черного пиксела, то выходим из процедуры
    if ((X =FromImage.Width) AND (Y = FromImage.Height)) then
        exit;

    // Если все нормально, начинаем обход по алгоритму жука
    ToLine:= ToImage.ScanLine[Y];
    ToLine[X]:= 0;

    // Поворачиваем налево (новое направление - север)
    cX := X;
    cY := Y - 1;

    Line := FromImage.ScanLine[cY];
    // Пока не придем в исходную точку, выделяем контур объекта

    while ((cX <> X) OR (cY <> Y)) do
    begin

       // В зависимости от текущего направления движения жука
        IF(Direct=1) then
        begin
                B := Line[cX];
                // Если элемент "черный", поворачиваем снова "налево"
                if (B < 255) then
                begin
                    ToLine := ToImage.ScanLine[cY];
                    ToLine[cX] := 0;
                    Direct := 4;
                    dec(cX);

                end
                // Иначе поворачиваем "направо"
                else
                begin
                    Direct := 2;
                    inc(cX);
                end;
        end;

           if(Direct=2) then
           begin
                 B := Line[cX];
                // Если элемент "черный", поворачиваем снова "налево"
                if (B < 255) then
                begin
                    ToLine := ToImage.ScanLine[cY];
                    ToLine[cX] := 0;
                    Direct := 1;
                    dec(cY);
                    Line := FromImage.ScanLine[cY];
                end
                // Иначе поворачиваем "направо"
                else
                begin
                    Direct := 3;
                    inc(cY);
                    Line := FromImage.ScanLine[cY];
                end;
           end;

            // Юг
            if(Direct=3) then
            begin

                B := Line[cX];
                // Если элемент "черный", поворачиваем снова "налево"
                if (B < 255) then
                begin
                    ToLine := ToImage.ScanLine[cY];
                    ToLine[cX] := 0;
                    Direct := 2;
                    inc(cX);
                end

                // Иначе поворачиваем "направо"

                else
                begin
                    Direct := 4;
                    dec(cX);
                end;

            end;

            // Запад
            if(Direct=4) then
            begin
                B := Line[cX];
                // Если элемент "черный", поворачиваем снова "налево"
                if (B < 255) then
                begin
                    ToLine := ToImage.ScanLine[cY];
                    ToLine[cX] := 0;
                    Direct := 3;
                    inc(cY);
                    Line := FromImage.ScanLine[cY];
                end
                // Иначе поворачиваем "направо"
                else
                    Direct := 1;
                    dec(cY);
                    Line := FromImage.ScanLine[cY];
                end;
            end;
       end;
 end;
DarkHacker вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Найти контур фигуры роман11 Помощь студентам 5 09.01.2015 13:04
Рассчитать контур заземления HellMercenariess Компьютерное железо 10 22.05.2013 11:25
Найти и выделить (либо закрасить) на изображении другое изображение DarkHacker PHP 0 13.08.2012 19:00
Найти и выделить штрих-код на изображении, реализация на С# или С++ Didos Общие вопросы C/C++ 1 21.05.2012 11:23